生产者与消费者模型

应用场景:不断的生产数据并且进行处理的场景

模型的特点

  1. 解耦合,生产者模块与消费者模块并不直接交互,都是仅操作线程安全的队列
  2. 支持忙闲不均,队列中有多个节点可以起缓冲作用
  3. 支持并发

生产者与消费者模型_第1张图片

生产者与消费者模型的实现:一个场所,两种角色,三种关系

生产者与生产者应该具备互斥关系
消费者与消费者应该具备互斥关系
生产者与消费者应该具备同步与互斥关系

代码实现:

#include 
#include 
#include 
#include 

//线程安全的阻塞队列---没有数据则消费者阻塞 / 数据满了则生产者阻塞

#define QUEUE_MAX 5
class BlockQueue{
public:
    BlockQueue(int maxq = QUEUE_MAX):_capacity(maxq){
        pthread_mutex_init(&_mutex, NULL);
        pthread_cond_init(&_pro_cond, NULL);
        pthread_cond_init(&_cus_cond, NULL);

    }
    ~BlockQueue(){

    }
    bool Push(int data){
        //生产者才会入队数据,如果队列中数据满了则需要阻塞
        pthread_mutex_lock(&_mutex);
        while(_queue.size() == _capacity){
            pthread_cond_wait(&_pro_cond, &_mutex);
        }
        _queue.push(data);
        pthread_mutex_unlock(&_mutex);
        pthread_cond_signal(&_cus_cond);
        return true;
    }
    bool pop(int *data){
        //出队都是消费者,有数据才能出队,没有数据要阻塞
        pthread_mutex_lock(&_mutex);
        while(_queue.empty()){
            pthread_cond_wait(&_cus_cond, &_mutex);
        }
        *data = _queue.front();
        _queue.pop();
        pthread_mutex_unlock(&_mutex);
        pthread_cond_signal(&_pro_cond);
        return true;
    }
private:
    std::queue<int> _queue;
    int _capacity;

    pthread_mutex_t _mutex;
    pthread_cond_t _pro_cond;
    pthread_cond_t _cus_cond;
};
void *thr_productor(void *arg){
    //这个参数是我们的主线程传递过来的线程
    BlockQueue *queue = (BlockQueue*)arg; //类型强转
    int i = 0;
    while(1){
        //生产者不断生产数据
        queue->Push(i);//通过Push接口操作queue中的成员变量
        printf("productor push data:%d\n", i++);
    }
    return NULL;
}
void *thr_customer(void *arg){
    BlockQueue *queue = (BlockQueue*)arg;
    while(1){
        //消费者不断获取数据进行处理
        int data;
        queue->pop(&data);
        printf("customer pop data:%d\n", data);
    }
    return NULL;
}

int main(){
    int ret ,i;
    pthread_t ptid[4], ctid[4];
    BlockQueue queue;

    for(i = 0; i<4; i++){
        ret = pthread_create(&ptid[i], NULL, thr_productor, (void*)&queue);
        if(ret != 0){
            printf("creat productor thread error\n");
            return -1;
        }
        ret = pthread_create(&ctid[i], NULL, thr_customer, (void*)&queue);
        if(ret != 0){
            printf("creat customer thread error\n");
            return -1;
        }
    }

    for(i = 0; i < 4; i++){
        pthread_join(ptid[i], NULL);
        pthread_join(ctid[i], NULL);
    }
    return 0;
}

运行结果:
生产者与消费者模型_第2张图片

你可能感兴趣的:(Linux,多线程)