一. 事件对象

      事件对象属于内核对象。包含三个成员:

    (1)使用计数

    (2)指明该事件是自动重置事件还是人工重置事件的布尔值

    (3)指明事件出于已通知状态还是未通知状态的布尔值。

二.人工重置事件和自动重置事件的区别

     当人工重置事件对象得到通知时,等待该事件对象的所有线程均变为可调度线程;当一个自动重置的事件对象得到通知时,等待该事件对象的线程中只有一个线程变为可调度线程,同时操作系统会将该事件对象设置为无信号状态,这样,当对所保护的代码执行完成之后,需要调用SetEvent函数将该事件对象设置为有信号状态。而人工重置的事件对象,在一个线程得到该事件对象之后,操作系统并不会将该事件对象设置为无信号状态,除非显示地调用ResetEvent函数将其设置为无信号状态,否则该对象会一直是有信号状态。

三.代码

 
  1. #include <windows.h>  
  2. #include <iostream.h>  
  3.  
  4. //线程入口函数声明  
  5. DWORD WINAPI Fun1Proc(  
  6.                         LPVOID lpParameter   // thread data  
  7.                         );  
  8.  
  9. DWORD WINAPI Fun2Proc(  
  10.                         LPVOID lpParameter   // thread data  
  11.                         );  
  12.  
  13. int tickets = 100;  //票数  
  14. HANDLE g_hEvent;    //事件对象句柄  
  15.  
  16. void main()  
  17. {   
  18.     //线程句柄  
  19.     HANDLE hThread1;  
  20.     HANDLE hThread2;   
  21.  
  22.     //创建人工重置事件内核对象  
  23.     g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);  
  24.  
  25.     //设置事件对象为有信号状态  
  26.     SetEvent(g_hEvent);  
  27.  
  28.     //创建线程  
  29.     hThread1 = CreateThread(NULL, 0, Fun1Proc, NULL, 0, NULL);  
  30.     hThread2 = CreateThread(NULL, 0, Fun2Proc, NULL, 0, NULL);  
  31.  
  32.     //关闭线程句柄,因为主线程不需要再对线程操作  
  33.     CloseHandle(hThread1);  
  34.     CloseHandle(hThread2);  
  35.  
  36.     //让主线程休眠4秒  
  37.     Sleep(4000);  
  38.  
  39.     //关闭事件对象句柄  
  40.     CloseHandle(g_hEvent);  
  41. }  
  42.  
  43.  
  44. //线程1的入口函数  
  45. DWORD WINAPI Fun1Proc(LPVOID lpParameter)  
  46. {  
  47.     while(TRUE)  
  48.     {  
  49.         //获取事件对象  
  50.         WaitForSingleObject(g_hEvent, INFINITE);  
  51.  
  52.         if( tickets>0)  
  53.         {  
  54.             Sleep(1);  
  55.             cout<<"thread1 sell ticket: "<<tickets--<<endl;  
  56.             SetEvent(g_hEvent);  
  57.         }  
  58.         else 
  59.         {  
  60.             SetEvent(g_hEvent);  
  61.             break;  
  62.         }  
  63.     }  
  64.     return 0;  
  65. }  
  66.  
  67.  
  68.  
  69. //线程2的入口函数  
  70. DWORD WINAPI Fun2Proc(LPVOID lpParameter)  
  71. {  
  72.     while(TRUE)  
  73.     {  
  74.         //获取事件对象  
  75.         WaitForSingleObject(g_hEvent, INFINITE);  
  76.  
  77.         if( tickets>0)  
  78.         {  
  79.             Sleep(1);  
  80.             cout<<"thread2 sell ticket: "<<tickets--<<endl;   
  81.             SetEvent(g_hEvent);  
  82.         }  
  83.         else 
  84.         {  
  85.             SetEvent(g_hEvent);  
  86.             break;  
  87.         }  
  88.     }  
  89.     return 0;  
  90. }  
  91.  
  92.  
  93.