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

WaitForMultipleObject与MsgWaitForMultipleObjects的用法

2012-10-30 17:22 507 查看
一、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;

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