秒杀多线程第六篇 经典线程同步 事件Event .

参考博客:http://blog.csdn.net/morewindows/article/details/7445233

使用Event来解决线程同步问题,Event其实是一个内核对象,下面列出相关的操作函数

1.创建事件

HANDLECreateEvent(

 LPSECURITY_ATTRIBUTESlpEventAttributes,

 BOOLbManualReset,

 BOOLbInitialState,

 LPCTSTRlpName

);

第一个参数:表示安全按控制一般传入NULL

第二个参数:确定事件是手动设置还是自动设置

      手动设置(TRUE):触发后允许所有线程执行,一直到关闭为止

      自动设置(FALSE):触发一次允许一个线程执行

                如果为自动置位,则对该事件调用WaitForSingleObject()

                  会自动调用ResetEvent()使事件变成未触发状态。

第三个参数:表示事件的初始状态,传入TRUE表示事件被触发

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

 

2.根据名称获得事件的句柄

 

HANDLEOpenEvent(

 

 DWORDdwDesiredAccess,

 

 BOOLbInheritHandle,

 

 LPCTSTRlpName     //名称

 

);

第一个参数:表示访问权限,对事件一般传入EVENT_ALL_ACCESS 

第二个参数表示事件句柄继承性,一般传入TRUE即可。

 

第三个参数表示名称,不同进程中的各线程可以通过名称来确保它们访问同一个事件。

 

3.触发事件(必须有一个或者多个线程等待调度

BOOLSetEvent(HANDLEhEvent);

4.将事件设为未触发状态

BOOLResetEvent(HANDLEhEvent);

4.事件的清理与销毁

CloseHandle();

 

 1 #include <stdio.h>
 2 #include <process.h>
 3 #include <windows.h>
 4 
 5 //定义事件句柄
 6 HANDLE  g_hThreadEvent;  
 7 
 8 //关键段的定义
 9 CRITICAL_SECTION  g_csThreadCode; 
10 long g_num; //登录次数
11 unsigned int __stdcall Fun(void *pPM); //线程函数
12 const DWORD THREAD_NUM = 10;//启动线程数
13 unsigned int __stdcall Fun(void *pPM)  
14 {  
15 //由于创建线程是要一定的开销的,所以新线程并不能第一时间执行到这来   
16     int nThreadNum = *(int *)pPM; //子线程获取参数   
17     SetEvent(g_hThreadEvent);//3.事件被触发
18     Sleep(50);//some work should to do  
19     EnterCriticalSection(&g_csThreadCode);//进入子线程序号的关键区域
20     g_num++;  //处理全局资源  
21     Sleep(0);//some work should to do   
22     printf("线程编号为%d  全局资源值为%d\n", nThreadNum, g_num);  
23     LeaveCriticalSection(&g_csThreadCode);
24     return 0;  
25 } 
26 int main()
27 {
28     printf("     CS的演示与Event\n");
29     g_num = 0;
30     g_hThreadEvent=CreateEvent(NULL,FALSE,FALSE,NULL);  //1.创建事件
31 
32     //关键段的初始化
33     InitializeCriticalSection(&g_csThreadCode);
34     HANDLE  handle[THREAD_NUM];
35     int i=0;
36     while (i<THREAD_NUM)
37     {
38         handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL);  
39         i++;
40         WaitForSingleObject(g_hThreadEvent,INFINITE);//2.等待事件被触发
41     }
42     
43     WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
44     CloseHandle(g_hThreadEvent);//5.销毁事件
45     //离开关键区域
46     LeaveCriticalSection(&g_csThreadCode);
47 
48     return 0;
49 }

 

运行结果:

结果发现线程号没有重复,且全局资源递增,说明主线程与子线程达到了同步,子线程之间形成了互斥

 

PulseEvent()来发出一个短暂的触发脉冲相当于同事调用

SetEvent(g_hThreadEvent); 

ResetEvent(g_hThreadEvent);

 

原文地址:https://www.cnblogs.com/yuqilihualuo/p/3023993.html