现在的位置: 首页 > 综合 > 正文

经典线程同步问题(三)

2018年06月08日 ⁄ 综合 ⁄ 共 1877字 ⁄ 字号 评论关闭

问题:

有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD。初始都为空。现要让四个文件呈如下格式:

A:1 2 3 4 1 2....

B:2 3 4 1 2 3....

C:3 4 1 2 3 4....

D:4 1 2 3 4 1....

请设计程序。

#include <fstream>
/*
整体思想如下:关键段实现对一个文件的互斥操作,用事件实现线程间同步
						至于事件与文件的对应关系,通过两个数组FileNow,NextFile来巧妙关联
						一个num始终对应一个event,对应一个Thread,FileNow与数组NextFile表示文件序列
						通过修改文件序列,实现Thread向不同文件书写
*/
const int FILE_COUNT =4;
const int EVENT_COUNT = 4;
const int THREAD_COUNT = 4;
CRITICAL_SECTION g_CS;
HANDLE g_events[EVENT_COUNT];
ofstream File[4];//4个文件
int FileNow[] = {0,1,2,3};
int NextFile[]={0,1,2,3};
unsigned int __stdcall ThreadFunc(LPVOID param)
{
	int num  = (int)param;//获取线程序列
	for (int i = 0; i<4; i++)
	{
		WaitForSingleObject(g_events[num],INFINITE);//申请到与该线程相对应的事件

		EnterCriticalSection(&g_CS);//进入共享段,互斥实现对文件的操作
		printf("线程%d正在向文件%c写入\n",num+1,FileNow[num]+'A');
		File[FileNow[num]]<<num+1<<' ';//序列号为num的线程向序列号为FileNow[num]的文件写入,也就是说哪个线程向哪个文件里写取决于FileNow[num]
		NextFile[(num+1)%FILE_COUNT] = FileNow[num];//改变下一轮写顺序
		Sleep(200);
		if (num+1 == FILE_COUNT)//一轮完毕
		{
			cout <<'\n';
			memcpy(FileNow,NextFile,sizeof(NextFile));
		}

		LeaveCriticalSection(&g_CS);
		SetEvent(g_events[(num+1)%EVENT_COUNT]);
	}
	
	return 0;
}
int main(int argc, char **argv)
{
	
	char fileName[] = "A.txt";
	for(int i = 0; i<FILE_COUNT; ++i)//创建4个文件
	{
		fileName[0]=i+'A';//不同的命名
		File[i].open(fileName,ios::trunc);
		if (File[i].fail())
		{
			cout <<"文件打开失败"<<endl;
			return -1;
		}

	}

	InitializeCriticalSection(&g_CS);//初始化关键段,实现对一个文件的互斥操作
    for (int i =0;i <EVENT_COUNT; ++i)
    {
		g_events[i] = CreateEvent(NULL,false,false,NULL);
    }
	SetEvent(g_events[0]);//手动设置事件0为释放状态,这样各线程就不陷于死等状态

	HANDLE hdl[THREAD_COUNT];
	for (int i = 0; i<THREAD_COUNT; ++i)
	{
		hdl[i] = (HANDLE)_beginthreadex(NULL,0,ThreadFunc,(LPVOID)i,0,NULL);//i就表示线程序列,将此序列通过参数传入线程函数,该函数通过参数辨别是哪个线程
	}
	
	
	WaitForMultipleObjects(THREAD_COUNT,hdl,true,INFINITE);
	//释放资源
	for (int i = 0; i<EVENT_COUNT; ++i)
	{
		CloseHandle(g_events[i]);
		CloseHandle(hdl[i]);
		
	}
	for (int i = 0; i<FILE_COUNT; ++i)
	{
		File[i].close();
	}
	DeleteCriticalSection(&g_CS);
	return 0;
}

文章参考:http://blog.csdn.net/lilien1010/article/details/8119325

抱歉!评论已关闭.