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 减 1。 如果此参数的值为零,则函数仅等待输入事件。

[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、Windows 8.1、Windows Server 2012 R2、Windows 10和Windows Server 2016: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_0nCount
线程的输入队列中提供了 dwWakeMask 参数中指定的类型的新输入。 PeekMessageGetMessageWaitMessage 等函数将队列中的消息标记为旧消息。 因此,调用其中一个函数后,在指定类型的新输入到达之前,不会返回对 MsgWaitForMultipleObjects 的后续调用。

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

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

如果互斥体正在保护永久性状态信息,则应检查它以确保一致性。

WAIT_TIMEOUT
258L
超时间隔已过,并且 bWaitAlldwWakeMask 参数指定的条件未得到满足。
WAIT_FAILED
(DWORD) 0xFFFFFFFF
函数失败。 要获得更多的错误信息,请调用 GetLastError。

注解

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

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

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

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

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

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

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

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

要求

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

另请参阅

MsgWaitForMultipleObjectsEx

同步函数

等待函数