一个经典的多线程同步问题03 事件Event

//创建事件

HANDLECreateEvent(
 
 LPSECURITY_ATTRIBUTESlpEventAttributes,
 
 BOOLbManualReset,
 
 BOOLbInitialState,
 
 LPCTSTRlpName
 
);

函数说明:

第一个参数表示安全控制,一般直接传入NULL。

第二个参数确定事件是手动置位还是自动置位,传入TRUE表示手动置位,传入FALSE表示自动置位。如果为自动置位,则对该事件调用WaitForSingleObject()后会自动调用ResetEvent()使事件变成未触发状态。打个小小比方,手动置位事件相当于教室门,教室门一旦打开(被触发),所以有人都可以进入直到老师去关上教室门(事件变成未触发)。自动置位事件就相当于医院里拍X光的房间门,门打开后只能进入一个人,这个人进去后会将门关上,其它人不能进入除非门重新被打开(事件重新被触发)。

第三个参数表示事件的初始状态,传入TRUR表示已触发。

第四个参数表示事件的名称,传入NULL表示匿名事件。

HANDLEOpenEvent(
 
 DWORDdwDesiredAccess,
 
 BOOLbInheritHandle,
 
 LPCTSTRlpName     //名称
 
);

//每次触发后,必有一个或多个处于等待状态下的线程变成可调度状态

BOOLSetEvent(HANDLEhEvent);

//将事件设为末触发

BOOLResetEvent(HANDLEhEvent);

//事件的清理与销毁

CloseHandle()

为了解决多线程问题,我们设置一个事件和一个关键段。用事件处理主线程与子线程的同步,用关键段来处理各子线程间的互斥。详见代码:

#include <stdio.h>  
#include <process.h>  
#include <windows.h>  
 
long lGlobVar = 0;//全局资源
//事件与关键段
HANDLE hEventPtrParam;
CRITICAL_SECTION csGlobVar;
 
unsigned int WINAPI ThreadProc(void* lpParam){
	//由于创建线程是要一定的开销的,所以新线程并不能第一时间执行到这来  
	int iThreadNo = *(int*)lpParam;
	SetEvent(hEventPtrParam);//触发事件  
	Sleep(50);//Do Sth
 
	EnterCriticalSection(&csGlobVar);
	lGlobVar++;//处理全局资源
	Sleep(50);//Do Sth
	printf("线程编号:%d,全局变量:%d.\n", iThreadNo, lGlobVar);
	LeaveCriticalSection(&csGlobVar);
	return 0;
}
 
void main()
{
	//初始化事件和关键段 自动置位,初始无触发的匿名事件
	hEventPtrParam = CreateEventW(NULL, FALSE, FALSE, NULL);
	InitializeCriticalSection(&csGlobVar);
 
 
	HANDLE hThreads[10];
	for(int i = 0; i < 10; i++){//等子线程接收到参数时主线程可能改变了这个i的值  
		hThreads[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, &i, 0, NULL);//创建线程
		WaitForSingleObject(hEventPtrParam, INFINITE);//等待事件被触发,等待到复位后,立马置位
	}
	//保证子线程已全部运行结束
	WaitForMultipleObjects(10, hThreads, TRUE, INFINITE);
	for(int i = 0; i < 10; i++){
		CloseHandle(hThreads[i]);//关闭线程句柄,使其内核对象计数减一
	}
 
 
	//销毁事件和关键段  
	CloseHandle(hEventPtrParam);
	DeleteCriticalSection(&csGlobVar);
}

可以看出来,经典线线程同步问题已经圆满的解决了——线程编号的输出没有重复,说明主线程与子线程达到了同步。全局资源的输出是递增的,说明各子线程已经互斥的访问和输出该全局资源。

猜你喜欢

转载自blog.csdn.net/CherishPrecious/article/details/81452335
今日推荐