四个线程写四个文件03 跨平台实现(Boost)

函数【extern void ConsoleOutput(bool bClient, char* lpszFmt, ...);】的具体实现

请参考博客《Boost.asio实现同步的TCP/IP通信》


#include<ctime>
#include<cstdio>
#include<iostream>
#include <fstream>
using namespace std;

#include <boost/thread.hpp>  
#include <boost/thread/mutex.hpp>  
using namespace boost;  

const int iThreadCnt = 4;//线程的个数
//所有子线程准备就绪的标志
bool bChilds[iThreadCnt] = {false, false, false, false};
boost::mutex muForLock;//互斥量
boost::condition_variable cvMain;//主线程通知子线程的条件变量
std::ofstream oFiles[iThreadCnt];//四个输出文件流
const int iTimes = 10;//每个线程输出数字序列的长度
int iCurr = 0;//当前输出数字的个数


extern void ConsoleOutput(bool bClient, char* lpszFmt, ...);
void WriteNumberIntoTxt(const int writedata){
	int iFileNo = writedata;//每个线程要写的数字【始终如一】
	while(iCurr < iTimes){
		{
			 mutex::scoped_lock oLock(muForLock); 
			 //初始的时候,条件不满足,所有子线程都陷入了等待中
			 while(!bChilds[writedata-1]){cvMain.wait(oLock);}
			 //为下一轮一起写文件做好准备
			 bChilds[writedata-1] = false;
		}
		//主线程对子线程最后一轮的唤醒只是为了让子线程正常退出
		if(iCurr >= iTimes)			break;
		this_thread::sleep(posix_time::seconds(rand()%3));
		iFileNo = (iFileNo+3)%iThreadCnt;
		oFiles[iFileNo] << writedata << " ";
	}
	ConsoleOutput(true, "Thread%d Exits\n", writedata);
}

void main()
{
	const char* lpszFileName[iThreadCnt] = {"A.txt", "B.txt", "C.txt", "D.txt"};
	boost::thread oThreads[iThreadCnt];
	for(int i = 0; i < iThreadCnt; i++){
		//打开文件【如果不存在则创建】
		oFiles[i].open(lpszFileName[i], std::ios_base::trunc);
		//创建线程【传递的参数为线程要写的数字】
		oThreads[i] = boost::thread(WriteNumberIntoTxt, i+1);
	}

	srand((unsigned)time(NULL));//设置随机数的种子

	for(; iCurr < iTimes; iCurr++){
		ConsoleOutput(false, "MainThread is Waiting...\n");
		//等待所有子线程准备就绪
		while(bChilds[0] || bChilds[1] || bChilds[2] || bChilds[3]){boost::this_thread::yield();}
		{
			mutex::scoped_lock oLock(muForLock);
			//满足所有子线程的条件
			for(int i = 0; i < iThreadCnt; i++)		bChilds[i] = true;
			//唤醒所有被阻塞的子线程
			cvMain.notify_all();
		}
		ConsoleOutput(false, "This round is %d.\n", iCurr);
	}
	//子线程可能在检测到退出条件(iCurr >= iTimes)之前陷入阻塞,无限等待
	{
		mutex::scoped_lock oLock(muForLock);
		for(int i = 0; i < iThreadCnt; i++)		bChilds[i] = true;
		//唤醒所有被阻塞的子线程
		cvMain.notify_all();
	}
	//等待线程执行结束
	for(int i = 0; i < iThreadCnt; i++)			oThreads[i].join();
	//关闭所有文件
	for(int i = 0; i < iThreadCnt; i++)			oFiles[i].close();
}

猜你喜欢

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