生产者与消费者模型特点:
- 解耦和,生产者模块与消费者模块并不直接交互,都是仅操作线程安全的队列
- 支持忙闲不均,队列中有对个节点可以起缓冲作用
- 支持并发
生产者与消费者模型的实现:
一个场所,两种角色,三种关系。
生产者与生产者应该具备互斥关系
消费者与消费者应该具备互斥关系。
生产者与消费者应该具备同步 + 互斥关系。
实现一个线程安全的队列 +多个角色的执行流
#include<iostream>
#include<queue>
using namespace std;
#define MAX_THR 4
class BlockQueue {
public:
BlockQueue(int qmax=5):_capacity(qmax)
{
//初始化资源
pthread_mutex_init(&_mutex, NULL);
pthread_cond_init(&_cond_pro, NULL);
pthread_cond_init(&_cond_con, NULL);
}
~BlockQueue() {
//释放资源。
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&_cond_pro);
pthread_cond_destroy(&_cond_con);
}
bool Push(int &data) {
//入队
pthread_mutex_lock(&mutex);
while (_queue.size() == _capacity) {
pthread_cond_wait(&_cond_pro, &mutex);
}
_queue.push(data);
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&_cond_con);
return true;
}
bool Pop(int *data) {
//出队
pthread_mutex_lock(&mutex);
while (_queue.empty()) {
pthread_cond_wait(&_cond_con, &mutex);
}
*data = _queue.front();
_queue.pop();
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond_pro);
return true;
}
private:
//c++stl是非线程安全的
queue<int> _queue;
int _capacity; //限制队列中节点的最大数量
pthread_mutex_t mutex; //互斥锁
pthread_cond_t _cond_pro; //生产者队列
pthread_cond_t _cond_con; //消费者队列
};
void * productor(void *arg) {
BlockQueue * q = (BlockQueue*)arg;
int i = 0;
while (1) {
//生产者不断的添加数据
q->Push(i);
cout << "productor " << pthread_self() << "---- put data:" << i++ << endl;
}
return NULL;
}
void * consumer(void * arg) {
BlockQueue *q = (BlockQueue*)arg;
while (1) {
//消费者不断的获取数据
int data;
q->Pop(&data);
cout << "consumer " << pthread_self() << "---- get data:" << data << endl;
}
return NULL;
}
int main() {
pthread_t ptid[MAX_THR], ctid[MAX_THR];
int ret, i;
BlockQueue q;
for (i = 0; i < MAX_THR; i++) {
ret = pthread_create(&ptid[i], NULL, productor, (void *)&q);
if (ret != 0) {
cout << "pthread create error\n" << endl;
return -1;
}
}
for (i = 0; i < MAX_THR; i++) {
ret = pthread_create(&ctid[i], NULL, consumer, (void *)&q);
if (ret != 0) {
cout << "pthread create error\n" << endl;
return -1;
}
}
for (i = 0; i < MAX_THR; i++) {
pthread_join(ctid[i], NULL);
pthread_join(ptid[i], NULL);
}
return 0;
}