• 多线程笔记2


    转发,请保持地址:http://blog.csdn.net/stalendp/article/details/9310171

    以前学习过Java的多线程设计,出于对java多线程设计的熟悉,我把pthread的多线程方法按照java的习惯封装了一下,并写了几个例子,分享一下。

    // ThreadHelper.h
    
    
    #ifndef threadTest_ThreadHelper_h
    #define threadTest_ThreadHelper_h
    
    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    void msleep(unsigned sec) {
        usleep(sec*1000);
    }
    
    // 参考 http://stackoverflow.com/questions/1151582/pthread-function-from-a-class
    class Thread {
    protected:
        std::string name;
        pthread_t mythread;
        pthread_mutex_t mymutex;
        pthread_cond_t mycond;
        
    protected:
        virtual void* run() = 0;
    public:
        Thread() {
            pthread_mutex_init(&mymutex, NULL);
            pthread_cond_init(&mycond, NULL);
            char msg[50];
            sprintf(msg, "%ld", time(NULL));
            name = msg;
        }
        
        Thread(const char* _name) : name(_name) {
            pthread_mutex_init(&mymutex, NULL);
            pthread_cond_init(&mycond, NULL);
        }
        
        virtual ~Thread() {
            pthread_mutex_destroy(&mymutex);
            pthread_cond_destroy(&mycond);
        }
        
        const char* getName() {
            return name.c_str();
        }
        
        void start() {
            if ( pthread_create( &mythread, NULL, _run, this) ) {
                printf("error creating thread.");
                abort();
            }
        }
        
    private:
        static void* _run(void* This) {
            return ((Thread*) This)->run();
        }
    };
    
    class Synchronizable {
    protected:
        pthread_mutex_t mymutex;
        pthread_cond_t mycond;
        
    public:
    #define LOCK_BEGIN  pthread_mutex_lock(&mymutex)
    #define LOCK_END    pthread_mutex_unlock(&mymutex)
    #define WAIT        pthread_cond_wait(&mycond, &mymutex)
    #define NOTIFY_ALL  pthread_cond_broadcast(&mycond);
        
    public:
        Synchronizable() {
            pthread_mutex_init(&mymutex, NULL);
            pthread_cond_init(&mycond, NULL);
        }
        
        virtual ~Synchronizable() {
            pthread_mutex_destroy(&mymutex);
            pthread_cond_destroy(&mycond);
        }
    
    };
    
    #endif


    然后给出一个生产消费者模式的例子:

    #ifndef threadTest_PtProducerConsumer_h
    #define threadTest_PtProducerConsumer_h
    
    #include "ThreadHelper.h"
    
    #include <pthread.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <time.h>
    #include <string>
    #include <vector>
    #include <sstream>
    
    // 生产者必须将数据安全地交给消费者。虽然只是这样的问题,但当生产者与消费者
    // 在不同的线程上运行时,两者的处理速度差将是最大的问题。当消费者要取数据时
    // 生产者还没有建立出数据,或是生产者建立出数据时消费者的状态还没办法接受数据等。
    // Producer-Consumer Pattern是在生产者和消费者之间加入一个“桥梁参与者”。
    // 以这个桥梁参与者缓冲线程之间的处理速度差。
    
    class Table : Synchronizable {
    private:
        int tail, head, count;
        std::vector<std::string> buffer;
        
    public:
        Table(int _count) : tail(0), head(0), count(0) {
            buffer.resize(_count);
        }
        
        void put(const char* cake) {
            LOCK_BEGIN;
            while (count >= buffer.size()) {
                printf("!!!TABLE IS FULL!!!
    ");
                WAIT;
            }
            buffer[tail] = cake;
            tail = (tail+1) % buffer.size();
            count++;
            NOTIFY_ALL;
            printf("puts  %s -- size %d
    ", cake, count);
            LOCK_END;
        }
        
        const char* take() {
            LOCK_BEGIN;
            while (count<=0) {
                printf("!!!NO MORE CAKES!!!
    ");
                WAIT;
            }
            std::string cake = buffer[head];
            head = (head+1) % buffer.size();
            count--;
            NOTIFY_ALL;
            printf("takes %s -- size %d
    ", cake.c_str(), count);
            LOCK_END;
            return cake.c_str();
        }
    };
    
    static int mid;
    
    class MakerThread: public Thread {
    private:
        Table* table;
    public:
        MakerThread(const char* _name, Table* _table) : Thread(_name) {
            this->table = _table;
            srand((unsigned)time(NULL));
        }
        void* run() {
            while (true) {
                msleep(rand()%1000);
                std::stringstream ss;
                ss << "[Cake No." << nextId() << " by " << getName()  << "]";
                table->put(ss.str().c_str());
            }
            return NULL;
        }
        
        static int nextId() {
            return mid++;
        }
    };
    
    class EaterThread: public Thread {
    private:
        Table* table;
    public:
        EaterThread(const char* _name, Table* _table) : Thread(_name) {
            this->table = _table;
        }
        
        void* run() {
            while (true) {
                const char* cake = table->take();
    //            printf("%s
    ", cake);
                msleep(rand()%1000);
            }
            return NULL;
        }
    };
    
    void pcRun() {
        Table* table = new Table(3);  // 建立可以放置3个蛋糕的桌子
        (new MakerThread("MakerThread-1", table))->start();
        (new MakerThread("MakerThread-2", table))->start();
        (new MakerThread("MakerThread-3", table))->start();
        (new EaterThread("EaterThread-1", table))->start();
        (new EaterThread("EaterThread-2", table))->start();
        (new EaterThread("EaterThread-3", table))->start();
        sleep(90);
        printf("hello producer consumer");
    }
    
    #endif


    参考:《Java多线程设计模式详解》

    相关文章: http://blog.csdn.net/stalendp/article/details/9253665

  • 相关阅读:
    线程池
    并发工具类
    并发编程专题
    HashMap底层源码剖析
    ConcurrentHashMap底层实现
    双列集合Map相关面试题
    Map与HashMap
    使用IDEA搭建一个 Spring + Spring MVC 的Web项目(零配置文件)
    一个oracle的实例(包含传参数)
    一个oracle的实例(包含定位错误)
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3186862.html
Copyright © 2020-2023  润新知