C++中Event使用

来源:互联网 发布:淘宝二手商品3c认证 编辑:程序博客网 时间:2024/06/10 16:22
标签: c++nullattributeswinapiobjectthread
 5049人阅读 评论(0) 收藏 举报

转载自:http://www.cnblogs.com/yuanzfy/archive/2011/08/26/2154460.html

之前线程同步用互斥锁Mutex或用户模式的CriticalSection等来进行同步,而且使用效果一直很好,直到最近遇到新问题,朋友推荐用事件去处理。但是对事件了解比较少,所以摘了篇文章看,另外自己做了下试验(所以代码不是转的哦)。

概念:

事件是用来同步地位不相等的线程的,事件可以用来使一个线程完成一件事情,然后另外的线程完成剩下的事情。

事件的使用很灵活,自动事件的激发态是由人工来控制的(超级重要,尤其是在需要精确掌控是否处于有信号状态的时候),而Mutex在释放(releaseMetux)后就一直处于激发态,直到线程WaitForSingleObject。事件可以用来控制经典的读写模型和生产者和消费者模型。相应的方式为,生成者等待消费者的消费,再消费者消费完后通知生产者进行生产。

Mutex是排他的占有资源,一般用于地位相等的线程进行同步。每个线程都可以排他的访问一个资源或代码段,不存在哪个线程对资源访问存在优先次序。一个线程只能在Mutex处于激发态的时候访问被保护的资源或代码段,线程可以通过WaitForSingelObject来等待Mutex,在访问资源完成之后,ReleaseMutex释放Mutex,此时Mutex处于激发态。

注意:对句柄使用WaitForSIngleObject()之后的副作用(句柄状态的自动变化)

Mutex具有成功等待的副作用,在用WaitForSingleObject()等待到Mutex后,Mutex自动变为无信号状态,直到调用ReleaseMutex()使Mutex变为有信号状态为止;

自动事件也具有成功等待的副作用;

手动事件没有,必须调用ResetEvent()使手动事件变为未激发态;

进程和线程也没有成功等待的副作用。当线程或者进程函数返回时,线程内核对象变为激发态,但WaitForSingleObject并没有使线程或者进程的内核对象变为未激发态。

总之,事件一般用于控制线程的先后顺序,而Mutex一般用于排他的访问资源。

Event的使用:

首先创建事件:

HANDLE CreateEvent(

  LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全属性

  BOOL bManualReset, // 复位方式,1为手动复位,0为自动复位

  BOOL bInitialState, // 初始状态,0为不可用状态即无信号,1为可用状态即有信号

  LPCTSTR lpName // 对象名称

  );

SetEvent()设置事件为有信号;ResetEvent()设置事件为无信号。

WaitForSingleObject()来等待Event变为有信号:

DWORD WaitForSignalObject(HANDLE hObject, DWORD dwMilliseconds);

返回值有以下几种:

WAIT_OBJECT_0 :表示等待对象已经变为有信号状态,如果设置为自动复位,还会把此信号再次变为无信号状态。

WAIT_TIMEOUT   :表示等待超时

WAIT_FAILED      :表示等待对象句柄是一个无效句柄。

代码示例:

功能:用主线程来等待子线程的执行结束

[cpp] view plain copy
  1. HANDLE hEvent;  
  2. int num=1;  
  3.   
  4. DWORD WINAPI _threadProc(LPVOID lpParam)  
  5. {  
  6.     for(int i=0; i<10000; i++)  
  7.     {  
  8.         for(int j=0; j<10000; j++)  
  9.             ;  
  10.     }  
  11.   
  12.     num=10;  
  13.     SetEvent(hEvent);  
  14.     return 0;  
  15. }  
  16.   
  17. void main()  
  18. {  
  19.     //手动复位,初始时无信号  
  20.     hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);  
  21.     if(hEvent==NULL)  
  22.     {     
  23.         printf("hEvent is null\n");  
  24.         return;  
  25.     }  
  26.   
  27.     HANDLE hThread=CreateThread(NULL, 0, _threadProc, NULL, 0, NULL);  
  28.   
  29.     DWORD dwRet=WaitForSingleObject(hEvent, INFINITE);  
  30.     if(dwRet==WAIT_ABANDONED)  
  31.         printf("WAIT_ABANDONED\n");  
  32.     else if(dwRet==WAIT_TIMEOUT)  
  33.         printf("WAIT_TIMEOUT\n");  
  34.     else if(dwRet==WAIT_OBJECT_0)  
  35.         printf("有信号状态\n");  
  36.     else if(dwRet==WAIT_FAILED)  
  37.         printf("WAIT_FAILED\n");  
  38.   
  39.     printf("sub thread run out, num is %d\n", num);  
1 0