生产者与消费者模型
生产者与消费者模型是经典的同步与互斥模型。
- 支持忙闲不均
- 支持并发
- 解耦合
有两类进程分别为消费者进程和生产者进程,对同一个临界资源进行访问,生产者不断生产产品,并将产品作为资源加入缓冲区,而消费者不断的消费缓冲区中的资源,利用信号量实现两类进程的同步与互斥。
其中生产者与生产者之间具有互斥关系;
消费者与消费者之间也具有互斥关系;
而生产者与消费者之间具有同步与互斥关系。
即一个场所,两类角色,三类关系。
利用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;
}
来源:CSDN
作者:weixin_44395170
链接:https://blog.csdn.net/weixin_44395170/article/details/103437803