线程同步之Win32API的Wait函数

来源:互联网 发布:java开发工具 百度云 编辑:程序博客网 时间:2024/05/17 08:19

线程同步之Win32API的Wait函数

Win32API中的Wait函数非常重要,很多同步都需要Wait函数的配合,Wait函数很多,常用的我就不赘述了,只对一些有用但不常用的函数做一些描述。

1.WaitForSingleObject

最常用的函数,不用多说了。对于信号灯和信号量,每用一次,信号量减一。

DWORD WaitForSingleObject(  HANDLE hHandle,        // handle to object  DWORD dwMilliseconds   // time-out interval);
2.WaitForSingleObjectEx
DWORD WaitForSingleObjectEx(  HANDLE hHandle,        // handle to object  DWORD dwMilliseconds,  // time-out interval  BOOL bAlertable        // alertable option);
基本上和WaitForSingleObject一致,所不同的在于WaitForSingleObjectEx = 
WaitForSingleObject(,,FALSE),也就是说在参数为TRUE的情况下可以进入线程告警状态,
可以使用APC机制。
3.WaitForMultipleObjects
DWORD WaitForMultipleObjects(  DWORD nCount,             // number of handles in array  CONST HANDLE *lpHandles,  // object-handle array  BOOL fWaitAll,            // wait option  DWORD dwMilliseconds      // time-out interval);
和WaitForSingleObject不同之处,在于等待多个句柄,这应该是一个与的关系,即是所有的句柄
都需要处于发信号的状态。
4.WaitForMultipleObjectsEx
DWORD WaitForMultipleObjectsEx(  DWORD nCount,             // number of handles in array  CONST HANDLE *lpHandles,  // object-handle array  BOOL fWaitAll,            // wait option  DWORD dwMilliseconds,     // time-out interval  BOOL bAlertable           // alertable option);
这个不需要多说什么了。
Note:现在介绍几种返回值
WAIT_OBJECT_0:状态处于发信号的状态。最合理的结束方式。
WAIT_TIMEOUT:超时退出。
WAIT_ABANDONED:针对Mutex对象,就是在owner线程退出之前也没有释放Mutex。
WAIT_FAILED:出错退出。需要使用GetLastErr.
下面的可以能有绕:
WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount – 1):
如果fWaitAll是TRUE,返回WAIT_OBJECT_0表示所有句柄都发了信号;
如果fWaitAll是FLASE,返回什么就是第几个句柄发了信号。
WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount – 1):
如果fWaitAll是TRUE,返回值WAIT_ABANDONED_0表示所有的线程发信号,至少一个线程退出;
如果fWaitAll是TRUE,至少一个线程退出,句柄就是返回值指的那个。
接着我们来看下面两个函数,一起说了:
DWORD MsgWaitForMultipleObjects(  DWORD nCount,          // number of handles in array  CONST HANDLE pHandles, // object-handle array  BOOL fWaitAll,         // wait option  DWORD dwMilliseconds,  // time-out interval  DWORD dwWakeMask       // input-event type);
DWORD MsgWaitForMultipleObjectsEx(  DWORD nCount,          // number of handles in array  CONST HANDLE pHandles, // object-handle array  DWORD dwMilliseconds,  // time-out interval  DWORD dwWakeMask,      // input-event type  DWORD dwFlags          // wait options);
我感觉这和WaitForMultipleObjects最大的区别在于,前者可以继续转消息泵,
而后者能把消息泵都停掉了,所以肯定收不到消息了。
特别提醒,fWaitAll,只能设置成FALSE,谨慎啊。
DWORD SignalObjectAndWait(  HANDLE hObjectToSignal,  // handle to object to signal  HANDLE hObjectToWaitOn,  // handle to object to watch  DWORD dwMilliseconds,    // time-out interval  BOOL bAlertable          // alertable option);
向一个句柄发一个信号,接着等待另一个句柄,用起来很简单,应该可用性很强。
最后说四个函数
BOOL RegisterWaitForSingleObject(   PHANDLE phNewWaitObject,       // wait handle  HANDLE hObject,                // handle to object  WAITORTIMERCALLBACK Callback,  // timer callback function  PVOID Context                  // callback function parameter  ULONG dwMilliseconds,          // time-out interval  ULONG dwFlags                  // options); 
这个函数测试了很久,才稍微有点一点心得。首先,Event一定要设定成自动的,
我因为这个问题吃尽苦头,然后可以当一个线程池来用,但是还有一个问题,
如下:
BOOL UnregisterWait(  HANDLE WaitHandle      // wait handle);
BOOL UnregisterWaitEx(  HANDLE WaitHandle,      // wait handle  HANDLE CompletionEvent  // completion event);
这个函数在使用的时候需要保护句柄,呵呵,否则系统很生气,后果很严重:)
建议使用INVALID_HANDLE_VALUE作为第二个参数,它会等到任务结束后,才注销。
VOID CALLBACK WaitOrTimerCallback(  PVOID lpParameter,        // thread data  BOOLEAN TimerOrWaitFired  // reason);
回调函数无需赘述。
 
原创粉丝点击