博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

boost thread condition_variable 条件变量

Posted on 2015-04-07 11:06  bw_0927  阅读(278)  评论(0)    收藏  举报
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/thread/recursive_mutex.hpp>
#include <boost/bind.hpp>

using namespace std;


int taskSize = 5;
int runningCount = 0;

boost::condition_variable_any condStart;
boost::condition_variable_any condStop;
boost::recursive_mutex condMut;
boost::recursive_mutex dataMut;

boost::recursive_mutex mut_io;

void threadProc(int n)
{
	do
	{
		{
			//cout是全局对象,需加锁
			boost::unique_lock<boost::recursive_mutex> io_lock(mut_io);
			cout << "thread "<< n << "waiting, " << runningCount << endl;
		}


		{
			boost::unique_lock<boost::recursive_mutex> lock(condMut);
			condStart.wait(lock);   //wait会自动解锁condMut,返回时又会重新获得锁,注意锁的范围,防止死锁
		}

		{
			boost::unique_lock<boost::recursive_mutex> lock(dataMut);
			runningCount++;
		}

	//	boost::this_thread::sleep(boost::posix_time::seconds(9));
		{
			boost::unique_lock<boost::recursive_mutex> io_lock(mut_io);
			cout << "i am thread "<< n << "waken, " << runningCount << endl;
		}

		while(true)
		{
			{
				boost::unique_lock<boost::recursive_mutex> io_lock(mut_io);
				cout << "thread "<< n << "doing job, " << runningCount << endl;
			}
			boost::this_thread::sleep(boost::posix_time::seconds(1));

			if(runningCount > taskSize)
			{
				boost::unique_lock<boost::recursive_mutex> lock(dataMut);
				runningCount--;
				break;
			}

			/*
			if(condStop.timed_wait(lock, boost::posix_time::seconds(1)))
			{
				runningCount--;
				break;
			}
			*/
		}
	}while(true);
}

int main()
{
	boost::thread_group grp;
	int totalThreadsCount = 5;
	for(int i=0; i<totalThreadsCount; i++)
	{
		grp.create_thread(boost::bind(&threadProc, i));
	}

	boost::this_thread::sleep(boost::posix_time::seconds(2));//sleep(2)给子线程机会运行


	std::srand(static_cast<unsigned int>(std::time(0)));
	int i = std::rand();

	{
		boost::lock_guard<boost::recursive_mutex> lock(condMut);
		for(int i=runningCount; i<taskSize; i++)
		{
			cout << "notify, " << std::rand() << endl;
			condStart.notify_one();  //唤醒一次
		}
	}



	boost::this_thread::sleep(boost::posix_time::seconds(10));

	{
		boost::lock_guard<boost::recursive_mutex> lock(dataMut);
		taskSize = 2;
	}  //注意锁的范围,别把condStart.notify_one();包含在dataMut锁范围内,否则当线程wake时会又一次获取dataMut锁,造成死锁
		/*
		condStop.notify_one();  
		*/


	boost::this_thread::sleep(boost::posix_time::seconds(10));
	{
		boost::lock_guard<boost::recursive_mutex> lock(dataMut);
		taskSize = 4;
	}
	for(int i=runningCount; i<taskSize; i++)
	{
		cout << "notify" << endl;
		condStart.notify_one();  //唤醒一次
	}


	boost::this_thread::sleep(boost::posix_time::seconds(5));
	condStart.notify_one();  //唤醒一次

	do
	{
		boost::this_thread::sleep(boost::posix_time::seconds(5));
		{
			boost::lock_guard<boost::recursive_mutex> lock(dataMut);
			taskSize = std::rand() % 10;
			cout << "taskSize: " << taskSize << endl;
		}

		if(runningCount < totalThreadsCount)
		{
			for(int i=runningCount; i<taskSize; i++)
			{
				cout << "notify" << endl;
				condStart.notify_one();  //唤醒一次
			}
		}
	}while(true);

//	boost::this_thread::sleep(boost::posix_time::seconds(10));
//	condStop.notify_one();  

//	boost::this_thread::sleep(boost::posix_time::seconds(10));
//	condStop.notify_all();  

	grp.join_all();  //join_all防止因为main线程退出导致所有子线程跟着结束 

//	boost::thread t1(boost::bind(&threadProc, 9));
//	t1.join();
	return 0;
}