Windows多线程同步系列之三-----事件对象

事件是一个内核事件,内核事件是什么呢,我理解也不深入也不好说,暂且理解为一个内核维护的数据类型吧通过内核事件同步主要

的方法是对事件的信号有和无来进行同步。

 

比如当我们一个线程进入一段临界代码(独占代码段,不可多个线程同时访问)那么这时候我们将事件对象设置为无信号状态。那么另外

一个线程便会在等待这样一个事件对象,直到该事件对象执行完临界代码,然后将事件对象设为有信号状态,此时便可以该线程便可进

临界代码段。

 

 

利用事件对象进行同步主要有以下几个API;

 

该函数用于创建一个匿名的事件对象,返回值为创建的事件对象

第一个参数为安全属性,当为NULL,设置为默认安全属性

第二个参数为手动或自动改变时间对象的信号状态。TRUE为手动。FALSE为自动

第三个参数为事件对象的初始化状态,TRUE为初始有信号状态,FALSE为初始无信号状态

第四个是事件对象的名称,NULL说明未匿名事件对象

 

一般情况下,我们选择创建一个默认安全属性,手工置位,初始为有信号状态,未命名的事件对象

 

 

该函数将事件对象置为有信号状态,成功则返回非零值,失败则返回零值。

 

 

该函数将事件对象置为无信号状态,成功则返回非零值,失败则返回零值

 

 

 

关闭事件对象,在程序结束之前。

 

该函数用于等待事件对象是否为有信号状态,如果为信号状态则返回,否则一直阻塞。其传入连个参数一个是事件对象,一个是超时

间隔。当第二个参数为INFINITE的时候该函数将一直阻塞知道事件被置为有信号状态。

 

 

我们还是以典型的卖票的例子来进行测试,代码实现如下:

 1 #include <windows.h>
 2 #include <stdio.h>
 3 
 4 static int number=10;
 5 HANDLE SigHand;
 6 
 7 DWORD WINAPI ThreadOne(LPVOID lpParameter)
 8 {
 9     printf("窗口1售票开始:\n");
10     while(1)
11     {
12         WaitForSingleObject(SigHand,INFINITE);
13         ResetEvent(SigHand);
14         if(number>0)
15         {
16             printf("窗口1售出第%d张票...\n",number);
17             number--;
18             Sleep(1000);        
19         }
20         SetEvent(SigHand);
21         Sleep(100);
22     }
23     return 0;
24 }
25 DWORD WINAPI ThreadTwo(LPVOID lpParameter)
26 {
27     printf("窗口2售票开始:\n");
28     while(1)
29     {
30         WaitForSingleObject(SigHand,INFINITE);
31         ResetEvent(SigHand);
32         if(number>0)
33         {
34             printf("窗口2售出第%d张票...\n",number);
35             Sleep(1000);
36             number--;
37         }
38         SetEvent(SigHand);
39         Sleep(100);
40     }
41     return 0;
42 }
43 
44 
45 int main()
46 {
47     HANDLE HOne,HTwo;
48     
49     printf("***********************vpoet******************\n");
50     HOne=CreateThread(NULL,0,ThreadOne,NULL,0,NULL);
51     HTwo=CreateThread(NULL,0,ThreadTwo,NULL,0,NULL);
52     SigHand=CreateEvent(NULL,TRUE,TRUE,NULL);
53     CloseHandle(HOne);
54     CloseHandle(HTwo);
55     while(TRUE)
56     {
57         if(number==0)
58         {
59             printf("不好意思,票卖完了!\n");
60             CloseHandle(SigHand);
61             return 0;
62         }
63         else
64         {
65             continue;
66         }    
67     }
68     
69     return 0;
70 }

运行截图:

posted @ 2015-07-29 15:40  vpoet  阅读(920)  评论(0编辑  收藏  举报