Boost.condition_variable_any实现生产者消费者的简单例子

Boost条件变量可以用来实现线程同步,它必须与互斥量配合使用。使用条件变量实现生产者消费者的简单例子如下,需要注意的是cond_put.wait(lock)是在等待条件满足。如果条件不满足,则释放锁,将线程置为waiting状态,继续等待;如果条件满足,则重新获取锁,然后结束wait,继续向下执行。

#include <stdio.h>    
#include <process.h>    
#include <windows.h> 


#include <iostream>
#include <string>
#include <stack>
using namespace std;


#include <boost/assign.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/thread.hpp>
using namespace boost;
using namespace this_thread;
using namespace boost::assign;

//一个生产者,两个消费者,四个缓冲区

mutex muConsole;//互斥访问缓冲区

//缓冲区对象
class CBuffer{
private:
	mutex muBuffer;
	condition_variable_any condPutInto;
	condition_variable_any condGetFrom;
	stack<int> stkBuffer;
	int iCapacity;//缓冲区的数量
	int iUnRead;//可读数据
private:
	bool IsFull(){ return (iUnRead == iCapacity);}
	bool IsEmpty(){ return (iUnRead == 0);}
public:
	CBuffer(int capacity){ iCapacity = capacity; iUnRead = 0;}
	void PutInto(int data){
		{
			mutex::scoped_lock oLock(muBuffer);
			//如果条件不满足,释放锁,阻塞线程
			while(IsFull()){condPutInto.wait(oLock);}
			stkBuffer.push(data);
			++iUnRead;
		}
		condGetFrom.notify_one();
	}
	void GetFrom(int& data){
		{
			mutex::scoped_lock oLock(muBuffer);
			//如果条件不满足,释放锁,阻塞线程
			while(IsEmpty()){condGetFrom.wait(oLock);}
			--iUnRead;
			data = stkBuffer.top(); stkBuffer.pop();
		}
		condPutInto.notify_one();
	}
};

//四个缓冲区的内存池
CBuffer oBuffer(4);

//生产者线程
void ProducerProc(int times, string name){
	for(int i = 0; i < times; i++){
		oBuffer.PutInto(i);
		muConsole.lock();
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);    
		cout << name << " put " << i << " into buffer." << endl;
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); 
		muConsole.unlock();
		
	}
}
//消费者线程
void ConsumerProc(int times, string name){
	int iData = -1;
	for(int i = 0; i < times; i++){
		oBuffer.GetFrom(iData);
		muConsole.lock();
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);    
		cout << name << " get " << iData << " from buffer." << endl;
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); 
		muConsole.unlock();
	}
}


void main()
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); 

	//创建线程对象,启动线程函数
	thread oProducer(ProducerProc, 8, "Producer");
	thread oConsumer1(ConsumerProc, 4, "Consumer1");
	thread oConsumer2(ConsumerProc, 4, "Consumer2");
		
	//等待所有线程结束执行
	oProducer.join();
	oConsumer1.join();
	oConsumer2.join();

	cout << endl << endl << "所有子线程都已经结束执行" << endl << endl;
}


猜你喜欢

转载自blog.csdn.net/knightonhourse/article/details/80208108