MsgWaitForMultipleObjects 函数 (winuser.h)

等待一个或多个指定对象处于信号状态或超时间隔过。 这些对象可以包含输入事件对象,可以使用 dwWakeMask 参数指定这些对象。

若要进入可警报的等待状态,请使用 MsgWaitForMultipleObjectsEx 函数。

语法

DWORD MsgWaitForMultipleObjects(
  [in] DWORD        nCount,
  [in] const HANDLE *pHandles,
  [in] BOOL         fWaitAll,
  [in] DWORD        dwMilliseconds,
  [in] DWORD        dwWakeMask
);

参数

[in] nCount

pHandles指向的数组中的对象句柄数。 最大对象句柄数为 MAXIMUM_WAIT_OBJECTS 减一。 如果此参数的值为零,则函数仅等待输入事件。

[in] pHandles

对象句柄数组。 有关可以指定句柄的对象类型的列表,请参阅以下“备注”部分。 数组可以包含不同类型的对象的句柄。 它可能不包含同一句柄的多个副本。

如果在等待仍在挂起时关闭其中一个句柄,则函数的行为未定义。

句柄必须具有 SYNCHRONIZE 访问权限。 有关详细信息,请参阅 标准访问权限

[in] fWaitAll

如果此参数 TRUE,则当 pHandles 数组中的所有对象的状态已设置为信号且已接收输入事件时,该函数将返回。 如果此参数 FALSE,则当任一对象的状态设置为信号或已接收输入事件时,该函数将返回。 在这种情况下,返回值指示其状态导致函数返回的对象。

[in] dwMilliseconds

超时间隔(以毫秒为单位)。 如果指定了非零值,则函数将等待指定对象发出信号或间隔。 如果 dwMilliseconds 为零,则如果未向指定对象发出信号,则函数不会进入等待状态;它始终会立即返回。 如果 dwMillisecondsINFINITE,则函数仅在发出指定对象的信号时返回。

Windows XP、Windows Server 2003、Windows Vista、Windows 7、Windows Server 2008 和 Windows Server 2008 R2:dwMilliseconds 值确实包括用于低功率状态的时间。 例如,当计算机处于睡眠状态时,超时确实会不断倒计时。

Windows 8 及更新版本、Windows Server 2012 及更新版本:dwMilliseconds 值不包括在低功率状态下花费的时间。 例如,当计算机处于睡眠状态时,超时不会不断倒计时。

[in] dwWakeMask

将输入事件对象句柄添加到对象句柄数组的输入类型。 此参数可以是 GetQueueStatus标志 参数中列出的值的任意组合。

返回值

如果函数成功,则返回值指示导致函数返回的事件。 它可以是以下值之一。 (请注意,WAIT_OBJECT_0 定义为 0,WAIT_ABANDONED_0 定义为 0x00000080L。

返回代码/值 描述
WAIT_OBJECT_0 到 (WAIT_OBJECT_0 + nCount– 1)
如果 bWaitAllTRUE,则指定范围内的返回值指示所有指定对象的状态已发出信号。 如果 bWaitAllFALSE,则返回值减去 WAIT_OBJECT_0 指示满足等待的对象 pHandles 数组索引。
WAIT_OBJECT_0 + nCount
dwWakeMask 参数中指定的类型的新输入在线程的输入队列中可用。 PeekMessageGetMessage等函数,WaitMessage 将队列中的消息标记为旧消息。 因此,在调用其中一个函数后,对 MsgWaitForMultipleObjects 的后续调用将不会返回,直到指定类型的新输入到达。

当出现需要线程操作的系统事件(例如前台激活)时,也会返回此值。 因此,MsgWaitForMultipleObjects 即使没有适当的输入可用,即使 dwWakeMask 设置为 0 也是如此。 如果发生这种情况,请调用 GetMessagePeekMessage 来处理系统事件,然后再再次尝试调用 MsgWaitForMultipleObjects

WAIT_ABANDONED_0 到 (WAIT_ABANDONED_0 + nCount– 1)
如果 bWaitAll为 TRUE,则指定范围内的返回值指示所有指定对象的状态已发出信号,并且至少有一个对象是放弃的互斥对象。 如果 bWaitAllFALSE,则返回值减去 WAIT_ABANDONED_0 指示已放弃的 mutex 对象的 pHandles 数组索引,该索引满足等待。 mutex 对象的所有权授予调用线程,互斥体设置为非对齐。

如果互斥体保护持久状态信息,则应检查它是否一致性。

WAIT_TIMEOUT
258L
未满足 bWaitAlldwWakeMask 参数指定的超时间隔和条件。
WAIT_FAILED
(DWORD)0xFFFFFFFF
函数失败。 若要获取扩展的错误信息,请调用 GetLastError

言论

MsgWaitForMultipleObjects 函数确定是否满足等待条件。 如果条件尚未满足,则调用线程将进入等待状态,直到满足等待条件的条件或超时间隔已过。

bWaitAllTRUE时,函数不会修改指定对象的状态,直到所有对象的状态都设置为信号。 例如,可以发出互斥体信号,但在其他对象的状态也设置为信号之前,线程不会获得所有权。 同时,其他一些线程可能会获取互斥体的所有权,从而将其状态设置为非对齐状态。

bWaitAllTRUE时,函数的等待仅当所有对象的状态设置为信号且已接收输入事件时才完成。 因此,将 bWaitAll 设置为 TRUE 可防止处理输入,直到 pHandles 数组中的所有对象的状态都设置为信号。 因此,如果将 bWaitAll 设置为 TRUE,则应在 dwMilliseconds中使用短超时值。 如果你有一个线程,该线程在 pHandles 数组中创建等待所有对象的窗口,包括由 dwWakeMask指定的输入事件,并且没有超时间隔,系统将死锁。 这是因为创建窗口的线程必须处理消息。 DDE 向系统中的所有窗口发送消息。 因此,如果线程创建窗口,请不要将 bWaitAll 参数设置为 TRUE,以调用从该线程 MsgWaitForMultipleObjects

bWaitAllFALSE时,此函数会检查数组中的句柄,从索引 0 开始,直到发出其中一个对象的信号。 如果多个对象被发出信号,该函数将返回数组中第一个句柄的索引,该句柄已发出信号。

在线程调用函数检查队列后,如果消息队列中存在指定类型的未读输入,则不会返回 msgWaitForMultipleObjects。 这是因为 PeekMessageGetMessageGetQueueStatus等函数,WaitMessage 检查队列,然后更改队列的状态信息,以便不再将输入视为新输入。 后续调用 MsgWaitForMultipleObjects 在指定类型的新输入到达之前不会返回。 现有的未读输入(上次线程检查队列之前收到)将被忽略。

该函数修改某些类型的同步对象的状态。 仅针对其信号状态导致函数返回的对象或对象进行修改。 例如,信号灯对象的计数减少一个。 有关详细信息,请参阅各个同步对象的文档。

MsgWaitForMultipleObjects 函数可以指定 pHandles 数组中以下任一对象类型的句柄:

  • 更改通知
  • 控制台输入
  • 事件
  • 内存资源通知
  • Mutex
  • 过程
  • 信号
  • 线
  • 可等待计时器

要求

要求 价值
最低支持的客户端 Windows XP [仅限桌面应用]
支持的最低服务器 Windows Server 2003 [仅限桌面应用]
目标平台 窗户
标头 winuser.h (包括 Windows.h)
User32.lib
DLL User32.dll

另请参阅

MsgWaitForMultipleObjectsEx

同步函数

等待函数