内核模式之事件
部分转载自: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; }
结果:
思考:
线程同步,就是让线程以一种有序的方式来执行。