您的位置:首页 > 移动开发 > Objective-C

WaitForMultipleObject与MsgWaitForMultipleObjects的用法

2012-12-24 16:43 531 查看
原文链接:http://blog.sina.com.cn/s/blog_827ed2e00100vqwv.html
一、WaitForSingleObject
函数功能: 等待一个内核对象变为已通知状态
可以使用WaitForSingleObject函数来等待一个内核对象变为已通知状态:
DWORD WaitForSingleObject(
HANDLE hObject, //指明一个内核对象的句柄
DWORD dwMilliseconds); //等待时间
该函数需要传递一个内核对象句柄,该句柄标识一个内核对象,如果该内核对象处于未通知状态,则该函数导致线程进入阻塞状态;如果该内核对象处于已通知状态,则该函数立即返回WAIT_OBJECT_0。第二个参数是函数的等待的时间,传递INFINITE指明要无限期等待,如果第为0,那么函数就测试同步对象的状态并立即返回。如果等待超时,该函数返回WAIT_TIMEOUT。如果该函数失败,返回WAIT_FAILED。可以通过下面的代码来判断:

DWORD dwResult = WaitForSingleObject(hProcess, 1000); //等待一个进程结束
switch (dwResult)
{
case WAIT_OBJECT_0:
// hProcess所代表的进程在5秒内结束
break;

case WAIT_TIMEOUT:
// 等待时间超过5秒
break;

case WAIT_FAILED:
// 函数调用失败,比如传递了一个无效的句柄
break;
}

二、WaitForMulitpleObjects
该函数来等待多个内核对象变为已通知状态:
DWORD WaitForMultipleObjects(

DWORD dwCount, //等待的内核对象个数

CONST HANDLE* phObjects, //一个存放被等待的内核对象句柄的数组

BOOL bWaitAll, //是否等到所有内核对象为已通知状态后才返回

DWORD dwMilliseconds); //等待时间

该函数的第一个参数指明等待的内核对象的个数,可以是0到MAXIMUM_WAIT_OBJECTS(64)中的一个值。phObjects参数是一个存放等待的内核对象句柄的数组。bWaitAll参数如果为TRUE,则只有当等待的所 有内核对象为已通知状态时函数才返回,如果为FALSE,则只要一个内核对象为已通知状态,则该函数返回。第四个参数和WaitForSingleObject中的dwMilliseconds参数类似。

返回值:

WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount - 1)时:如果bWaitAll为TRUE,返回值指示等待的对象被触发了,如果bWaitAll为FALSE,返回值减去WAIT_OBJECT_0指示对象数组的索引,也就是哪一个对象被触发了。

WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount - 1)时:如果bWaitAll为FALS,返回值指示等待的对象被触发了,并且至少有一个abandoned互斥对象,如果bWaitAll为FALSE,返回值减去WAIT_ABANDONED_0指示abandoned互斥对象的索引。

WAIT_TIMEOUT:表示超时了,并且bWaitAll明确的所有条件都不满足。

WAIT_FAILED:函数调用失败。

三、MsgWaitForMultipleObjects
函数功能:阻塞时仍可以响应消息
MsgWaitForMultipleObjects()函数类似WaitForMultipleObjects(),但它会在“对象被激发”或“消息到达队列”时被唤醒而返回。MsgWaitForMultipleObjects()多接收一个参数,允许指定哪些消息是观察对象。

DWORD MsgWaitForMultipleObjects(
DWORD nCount, // 表示pHandles数组的元素个数,最大容量是MAXIMUM_WAIT_OBJECTS
LPHANDLE pHandles, // 指向一个由对象handles组成的数组,这些handles的类型不需要相同
BOOL fWaitAll, // 是否等待所有的handles被激发才返回
DWORD dwMilliseconds, // 超时时间
DWORD dwWakeMask // 欲观察的用户输入消息类型
);

参数
dwWakeMask
欲观察的用户输入消息类型: Value Meaning
QS_ALLEVENTS An input, WM_TIMER, WM_PAINT, WM_HOTKEY, or posted message is in the queue.
QS_ALLINPUT Any message is in the queue.
QS_ALLPOSTMESSAGE A posted message (other than those listed here) is in the queue.
QS_HOTKEY A WM_HOTKEY message is in the queue.
QS_INPUT An input message is in the queue.
QS_KEY A WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, or WM_SYSKEYDOWN message is in the queue.
QS_MOUSE A WM_MOUSEMOVE message or mouse-button message (WM_LBUTTONUP, WM_RBUTTONDOWN, and so on).
QS_MOUSEBUTTON A mouse-button message (WM_LBUTTONUP, WM_RBUTTONDOWN, and so on).
QS_MOUSEMOVE A WM_MOUSEMOVE message is in the queue.
QS_PAINT A WM_PAINT message is in the queue.
QS_POSTMESSAGE A posted message (other than those just listed) is in the queue.
QS_SENDMESSAGE A message sent by another thread or application is in the queue.
QS_TIMER A WM_TIMER message is in the queue

返回值
WAIT_TIMEOUT :因时间终了而返回
WAIT_OBJECT_0 :当bWaitAll是TRUE
WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount – 1) :bWaitAll是FALSE,将返回值减去WAIT_OBJECT_0,就表示数组中哪一个handle被激发了
WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount – 1) :等待的对象中有任何mutexes
WAIT_FAILED :函数失败时返回该值
WAIT_OBJECT_0 + nCount :消息到达队列

MsgWaitForMultipleObjects()的正确使用方式是改写主消息循环,使得激发状态的handles得以像消息一样被对待。通常程序中只会有一个地方调用MsgWaitForMultipleObjects(),而这个调用存在于消息循环中。
注意:
1. 在收到WM_QUIT之后,Windows仍然会传送消息给你,如果要在收到WM_QUIT之后等待所有线程结束,必须继续处理你的消息,否则窗口会变得反应迟钝,而且没有重绘能力。
2.MsgWaitForMultipleObjects()不允许handles数组中有缝隙产生。所以当某个handle被激发了时,应该在下一次调用MsgWaitForMultipleObjects之前先把handles数组做个整理、紧压,不要只是把数组中的handle设为NULL
3.如果有另一个线程改变了对象数组,而那是你正在等待的,那么需要一种方法,可以强迫MsgWaitForMultipleObjects返回,并重新开始,以包含新的handle
可以向下面这样使用:
// 移除读到的所有的消息,防止界面锁住

while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))

{

if(msg.message == WM_QUIT)

return;

DispatchMessage(&msg);

}

// 等待任何队列消息或者hThread线程句柄被触发

result = MsgWaitForMultipleObjects(1, &hThread, FALSE, INFINITE, QS_ALLINPUT);

if(result == WAIT_OBJECT_0)

{

break;

}

else

{

continue;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: