用一个队列创建一个仓库,生产线程往里加数据,而消费者在里面读。
如果仓库满了,消费者无法生产,如果仓库为0,消费者线程无法使用
#include <iostream>
#include<pthread.h>
#include<queue>
#define MAX_Queue 10
using namespace std ;
class Blockqueue{ //生产者消费者队结构体
private:
queue <int> _queue; //用于放数据的队列
pthread_cond_t _cond_product;//生产者条件变量
pthread_cond_t _cond_consumer;//消费者条件变量
pthread_mutex_t _mutex;//用于互斥的锁
int _capacity;//队列容量 因为queue结构体可以无限扩容,如果没有容量限制可能导致资源耗尽程序崩溃
public:
Blockqueue(int cap = MAX_Queue):_capacity(cap){ //构造函数初始化数据
pthread_cond_init(&_cond_product,NULL);
pthread_cond_init(&_cond_consumer,NULL);
pthread_mutex_init(&_mutex,NULL);
}
~Blockqueue() { //析构函数销毁条件变量 互斥锁
pthread_cond_destroy(&_cond_product);
pthread_cond_destroy(&_cond_consumer);
pthread_mutex_destroy(&_mutex);
}
bool QueuePush(int data)
{ //在队列中放入元素 相当于生产
//进来先上锁,防止别人访问,互斥
pthread_mutex_lock(&_mutex);
while(_queue.size() == _capacity)//循环判断防止其他线程先于此线程唤醒从而引发错误
{ //如果容量满了,将其加入到条件变量中 分三步 解锁 然后休眠 被唤醒后加锁
pthread_cond_wait(&_cond_product,&_mutex);
}//如果while循环结束那么意味着有容量于是插入
_queue.push(data);
pthread_mutex_unlock(&_mutex);//开锁
pthread_cond_signal(&_cond_consumer);//唤醒消费者线程
}
//消费者线程 原理同上只不过 条件不一样
bool QueuePop(int &data){
pthread_mutex_lock(&_mutex);
while(_queue.size() == 0){
pthread_cond_wait(&_cond_consumer,&_mutex);
}
data = _queue.front();//获取队列头元素
_queue.pop();//头元素出队列
pthread_mutex_unlock(&_mutex);
pthread_cond_signal(&_cond_product);
}
};//消费者函数
void* thr_consumer(void*arg)
{
Blockqueue* q=(Blockqueue*)arg;
int i=0;
while(1){
q->QueuePop(i);
cout<<"_consumer消费者 "<< i<<endl;
}
return 0;
}
//生产者函数
void* thr_producer(void*arg)
{
Blockqueue* q= (Blockqueue*)arg;
int i=0 ;
while(1){
q->QueuePush(i++);
}
return 0;
}
int main(){
pthread_t t[4],pro_tid[4]; //线程变量 当创建线程后值为线程额ID,也是线程的地址
int ret;
Blockqueue q;
//创建四个消费者线程
for(int i=0;i<4;i++)
{
ret=pthread_create(&t[i],NULL,thr_consumer,(void*)(&q));
if(ret!=0)
{
cout<<" thread creataeo"<<endl;
}
}
//四个生产者线程
for(int i=0;i<4;i++)
{
ret=pthread_create(&pro_tid[i],NULL,thr_producer,(void*)(&q));
if(ret!=0)
{
cout<<" thread creataeo"<<endl;
}
}
//获取线程的返回值,NULL代表不关心返回值只为了主函数能退出
for(int i=0;i<4;i++)
{
pthread_join(t[i],NULL);
}
for(int i=0;i<4;i++)
{
pthread_join(pro_tid[i],NULL);
}
return 0;
}
makefile编码:
ConsumerQueue:ConsumerQueue.cpp
2 g++ -g $^ -o $@ -lpthread
需要链接库