内核模式之事件

部分转载自:http://blog.csdn.net/morewindows/article/details/7445233

步骤:

  1、CreateEvent,创建一个事件内核对象。

  2、SetEvent,将一个事件内核对象设为触发状态。而WaitForSingleObject函数就是等待一个事件被触发后,才继续执行。其实就相当于一个通电开关,按下了,才通电,通电了,才能继续执行。

  3、ResetEvent,将一个事件内核对象设为未触发状态。

  4、CloseHandle,关闭内核对象。

 

事件内核对象的个人理解:

  1、事件对象可以分为2种,一种为自动重置事件,别一种为手动重置事件。

     自动重置事件:当线程成功等待到自动重置对象的时候,对象就会自动重置为未触发状态,而且只允许一个线程得到自动重置对象。。一定记住是一等到,马上就重置了。

     手动重置事件:必须手动将一个事件对象重置,或者线程结束时自动重置。但是手动重置事件允许多个线程得到事件。所以由于这种特性,所以拖动重置事件,一般只用来对只读的数据进行处理,否则可能出现不可预料的结果。

  2、事件对象,就如《windows核心编程》中所说的,就是一面旗帜,当有这个信号时,就执行操作。

 

代码:

#include <stdio.h>
#include <process.h>
#include <windows.h>
long g_nNum;
unsigned int __stdcall Fun(void *pPM);
const int THREAD_NUM = 10;

//事件与关键段
HANDLE  g_hThreadEvent;
CRITICAL_SECTION g_csThreadCode;
int main()
{
	printf("     经典线程同步 事件Event\n");
	printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");
	//初始化事件和关键段 自动置位,初始无触发的匿名事件
	g_hThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 
	InitializeCriticalSection(&g_csThreadCode);

	HANDLE  handle[THREAD_NUM];	
	g_nNum = 0;
	int i = 0;
	while (i < THREAD_NUM) 
	{
		handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL);
		WaitForSingleObject(g_hThreadEvent, INFINITE); //等待事件被触发
		i++;
	}
	WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);

	//销毁事件和关键段
	CloseHandle(g_hThreadEvent);
	DeleteCriticalSection(&g_csThreadCode);
	return 0;
}
unsigned int __stdcall Fun(void *pPM)
{
	int nThreadNum = *(int *)pPM; 

	g_nNum++;
	printf("线程编号为%d  全局资源值为%d\n", nThreadNum, g_nNum); 

	SetEvent(g_hThreadEvent); //触发事件
	return 0;
}

 结果:

 

思考:

  线程同步,就是让线程以一种有序的方式来执行。

posted @ 2013-09-23 12:49  Fly Hawk  阅读(712)  评论(0编辑  收藏  举报