生产者与消费者模型

我的梦境 提交于 2019-12-10 05:42:05

生产者与消费者模型

生产者与消费者模型是经典的同步与互斥模型。

  • 支持忙闲不均
  • 支持并发
  • 解耦合

有两类进程分别为消费者进程生产者进程,对同一个临界资源进行访问,生产者不断生产产品,并将产品作为资源加入缓冲区,而消费者不断的消费缓冲区中的资源,利用信号量实现两类进程的同步与互斥。

其中生产者与生产者之间具有互斥关系;
消费者与消费者之间也具有互斥关系;
而生产者与消费者之间具有同步与互斥关系。
即一个场所,两类角色,三类关系。

利用C++封装一个线程安全的队列,实现生产者与消费者模型:

#include <iostream>
#include <queue>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

#define MAX_QUE 10

class BlockQueue
{
    private:
        std::queue<int> _queue;  // 动态增长的队列
        int _capacity;  // 队列最大容量
        pthread_cond_t _cond_productor;  // 生产者等待队列
        pthread_cond_t _cond_consumer;  // 消费者等待队列
        pthread_mutex_t _mutex;  // 实现互斥
    public:
        BlockQueue(int queNum = MAX_QUE):_capacity(queNum)
        {
            pthread_mutex_init(&_mutex, NULL);
            pthread_cond_init(&_cond_consumer, NULL);
            pthread_cond_init(&_cond_productor, NULL);
        }
        ~BlockQueue()
        {
            pthread_mutex_destroy(&_mutex);
            pthread_cond_destroy(&_cond_consumer);
            pthread_cond_destroy(&_cond_productor);
        }
        // 提供给生产者的接口,数据入队
        bool QueuePush(int &data)
        {
            pthread_mutex_lock(&_mutex);
            while (_queue.size() == _capacity)  // 判断队列结点是否已满
                pthread_cond_wait(&_cond_productor, &_mutex);
            _queue.push(data);
            pthread_mutex_unlock(&_mutex);
            pthread_cond_signal(&_cond_consumer);
        }
        // 提供给消费者的接口,数据出队
        bool QueuePop(int &data)
        {
            pthread_mutex_lock(&_mutex);
            while (_queue.empty())
                pthread_cond_wait(&_cond_consumer, &_mutex);
            data = _queue.front();
            _queue.pop();
            pthread_mutex_unlock(&_mutex);
            pthread_cond_signal(&_cond_productor);
            return true;
        }
};

void *ThrConsumer(void *arg)
{
    BlockQueue *queue = (BlockQueue*)arg;
    while (1)
    {
        int data;
        queue->QueuePop(data);
        printf("++get a data: %d\n", data);
    }
}

void *ThrProductor(void *arg)
{
    int i = 0;
    BlockQueue *queue = (BlockQueue*)arg;
    while (1)
    {
        queue->QueuePush(i);
        printf("--put a data: %d\n", i++);
    }
}

#define MAX_THR 4
int main()
{
    int i = 0, ret = 0;
    pthread_t ctid[MAX_THR], ptid[MAX_THR];
    BlockQueue q;

    for (i = 0; i < MAX_THR; i++)
    {
        ret = pthread_create(&ctid[i], NULL, ThrConsumer, (void*)&q);
        if (ret != 0)
        {
            std::cerr << "thread create error\n";
            return -1;
        }
    }
    for (i = 0; i < MAX_THR; i++)
    {
        ret = pthread_create(&ptid[i], NULL, ThrProductor, (void*)&q);
        if (ret != 0)
        {
            std::cerr << "thread create error\n";
            return -1;
        }
    }

    for (i = 0; i < MAX_THR; i++)
    {
        pthread_join(ctid[i], NULL);
        pthread_join(ptid[i], NULL);
    }
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!