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; }