生产者消费者问题 / condition_variable的用法

1、

// condition_variable::notify_one
#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
using namespace std; 
std::mutex mtx;
std::condition_variable produce,consume;
 
int cargo = 0;     // shared value by producers and consumers
 
void consumer () {
  std::unique_lock<std::mutex> lck(mtx);
  cout << "before consumer wait " << endl;
  while (cargo==0) consume.wait(lck);
  std::cout << cargo << '\n';
  cargo=0;
  cout << "consumer cargo : " << cargo << endl;
  cout << "this is consumer " << endl;
  produce.notify_one();
}
 
void producer (int id) {
  std::unique_lock<std::mutex> lck(mtx);
  cout << "before producer wait " << endl;
  while (cargo!=0) produce.wait(lck);
  cargo = id;
  cout << "producer cargo : " << cargo << endl;
  cout << "this is producer " << endl;
  consume.notify_one();
}
 
int main ()
{
  std::thread consumers[10],producers[10];
  // spawn 10 consumers and 10 producers:
  for (int i=0; i<10; ++i) {
    consumers[i] = std::thread(consumer);
    producers[i] = std::thread(producer,i+1);
  }
 
  // join them back:
  for (int i=0; i<10; ++i) {
    producers[i].join();
    consumers[i].join();
  }
 
  return 0;
}

 2、

 

//生产者-消费者问题3
#include<iostream>
#include<mutex>
#include<thread>
#include<string>
#include <condition_variable>
 
using namespace std;
 
//预处理
#define MAX 10//缓冲池的最大数量
 
//全局变量的定义
mutex m;//建立一个互斥信号量m
condition_variable full_con;//如果某时刻缓冲池为满,那么就让full_con等待
condition_variable empty_con;//如果某时刻缓冲池为空,那么就让empty等待
string buffer[MAX];//建立一个最大数量为MAX的缓冲池,此缓冲池采用循环队列的形式
int pro_num = 0;//用pro_num来记录生产者在缓冲池的当前位置
int con_num = 0;//用con_num来记录消费者在缓冲池的当前位置
int pro_index = 0;//用index来记录现在是第几个被生产者生产的产品
 
//生产者类
class producer{
private:
	string in;//生产的产品
	int index;//用来标记现在是第几个生产者
	
public:
	//带默认形参的构造函数
	producer( string in = "", int index = 0 ) : in( in ), index( index ){
	} 
	
	//调用系统默认的析构函数
	~producer( ) = default;
	
	//生产产品,用time来决定循环几次
	void produce( );
};
 
class consumer{
private:
	string out;//消费的产品
	int index;//用来标记现在是第几个消费者
	
public:
	//带默认形参的构造函数
	consumer( string out = "", int index = 0 ) : out( out ), index( index ){
	}
	
	//调用系统默认的析构函数
	~consumer( ) = default;
	
	//消费产品
	void consume( );
};
 
//生产产品函数的实现
void producer::produce( ){
		in = "生产者“" + to_string( this->index ) + "”生产的产品" + to_string( pro_index++ );//生产的产品
		unique_lock lock( m );//锁住互斥变量m,避免消费者动用缓冲池buffer
		while(( pro_num + 1 ) % MAX == con_num ){//判断缓冲池已满
			cout << "【!!!】缓冲池已满,生产者“" << index << "”在等待一个空位" << endl;
			full_con.wait( lock );//让full进入等待状态
		}
		buffer[pro_num] = in;//将生产者生产的产品放入缓冲池
		pro_num = ( pro_num +1 ) % MAX;
		cout << in << endl;	
		empty_con.notify_all();//唤起empty	
}
 
//消费产品函数的实现
void consumer::consume(){
		unique_lock lock( m );//锁住互斥变量m,避免生产者动用缓冲池buffer
		while( pro_num == con_num ){//判断缓冲池为空
			cout << "【!!!】缓冲池为空,消费者“" << index << "”在等待一件产品" << endl;
			empty_con.wait( lock );
		}
		out = "消费者“" + to_string( this->index ) + "”消费了" + buffer[con_num];//消费者消费的产品
		con_num = ( con_num + 1 ) % MAX;//将生产者生产的产品从缓冲池取出
		cout << out << endl;	
		full_con.notify_all();//唤起full
}
 
//定义了一个函数,让生产者生产50次产品
void producer_work( producer p ) {
	int i = 0;
	while( i < 50 ){
		p.produce( );
		i++;
	}
}
 
//定义了一个函数,让消费者消费50次产品	
void consumer_work( consumer c ){
	int i = 0;
	while( i < 50 ){
		c.consume( );
		i++;
	}
}
  
int main( void ){
	producer p;
	consumer c;
	thread pro( producer_work, p );
	thread con( consumer_work, c);
	pro.join( );
	con.join( );
	return 0;
}

 3、condition_variable的用法

#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <vector>
using namespace std;

mutex mtx;
condition_variable cv;
bool ready = false;

void print(int idx)
{
    unique_lock<mutex> lck(mtx);
    while(!ready)  cv.wait(lck);
    cout << "idx : " << idx << endl;
}

void go()
{
    unique_lock<mutex> lck(mtx);
    ready = true;
    cv.notify_all();
}

int main()
{
    vector<thread> threads;
    for(int i =0; i < 10; i++)
    {
        threads.push_back(thread(print, i));
    }
    go();
    for(auto& r : threads)
    {
        r.join();
    }
    return 0;
}

 

posted @ 2023-04-27 14:17  小丑_jk  阅读(33)  评论(0编辑  收藏  举报