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 为零,则如果未向指定对象发出信号,则函数不会进入等待状态;它始终立即返回。 如果 dwMilliseconds 为 INFINITE,则仅当指定对象发出信号时,函数才会返回。
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.)
返回代码/值 | 说明 |
---|---|
|
如果 bWaitAll 为 TRUE,则指定范围内的返回值指示所有指定对象的状态都已发出信号。 如果 bWaitAll 为 FALSE,则返回值减去 WAIT_OBJECT_0 表示满足等待的对象的 pHandles 数组索引。 |
|
线程的输入队列中提供了 dwWakeMask 参数中指定的类型的新输入。 PeekMessage、GetMessage 和 WaitMessage 等函数将队列中的消息标记为旧消息。 因此,调用其中一个函数后,在指定类型的新输入到达之前,不会返回对 MsgWaitForMultipleObjects 的后续调用。
发生需要线程操作的系统事件(例如前台激活)时,也会返回此值。 因此, MsgWaitForMultipleObjects 可以返回,即使没有可用的适当输入,即使 dwWakeMask 设置为 0。 如果发生这种情况,请在再次尝试调用 MsgWaitForMultipleObjects 之前调用 GetMessage 或 PeekMessage 来处理系统事件。 |
|
如果 bWaitAll 为 TRUE,则指定范围内的返回值指示所有指定对象的状态都已发出信号,并且至少有一个对象是放弃的互斥对象。 如果 bWaitAll 为 FALSE,则返回值减去 WAIT_ABANDONED_0 表示已放弃的互斥对象的 pHandles 数组索引满足等待。 互斥对象的所有权授予调用线程,互斥体设置为非签名。
如果互斥体正在保护永久性状态信息,则应检查它以确保一致性。 |
|
超时间隔已过,并且 bWaitAll 和 dwWakeMask 参数指定的条件未得到满足。 |
|
函数失败。 要获得更多的错误信息,请调用 GetLastError。 |
注解
MsgWaitForMultipleObjects 函数确定是否满足等待条件。 如果未满足条件,调用线程将进入等待状态,直到满足等待条件或超时间隔已过。
当 bWaitAll 为 TRUE 时,函数不会修改指定对象的状态,直到所有对象的状态都设置为信号。 例如,可以向互斥体发出信号,但在其他对象的状态也设置为信号之前,线程不会获得所有权。 同时,其他一些线程可能会获得互斥锁的所有权,从而将其状态设置为非签名。
当 bWaitAll 为 TRUE 时,仅当所有对象的状态都设置为已发出信号并且已收到输入事件时,函数的等待才会完成。 因此,将 bWaitAll 设置为 TRUE 会阻止处理输入,直到 pHandles 数组中所有对象的状态都设置为信号。 出于此原因,如果将 bWaitAll 设置为 TRUE,则应使用 dwMilliseconds 中的短超时值。 如果你有一个线程创建窗口,等待 pHandles 数组中的所有对象,包括 dwWakeMask 指定的输入事件,且没有超时间隔,则系统将死锁。 这是因为创建窗口的线程必须处理消息。 DDE 将消息发送到系统中的所有窗口。 因此,如果线程创建窗口,请不要在调用从该线程发出的 MsgWaitForMultipleObjects 时将 bWaitAll 参数设置为 TRUE。
当 bWaitAll 为 FALSE 时,此函数将按从索引 0 开始的顺序检查数组中的句柄,直到向其中一个对象发出信号。 如果多个对象被发出信号,函数将返回数组中第一个句柄的索引,该句柄已发出对象信号。
如果在线程调用函数以检查队列后,消息队列中存在指定类型的未读输入,则 MsgWaitForMultipleObjects 不会返回。 这是因为 PeekMessage、GetMessage、GetQueueStatus 和 WaitMessage 等函数检查队列,然后更改队列的状态信息,使输入不再被视为新输入。 在指定类型的新输入到达之前,对 MsgWaitForMultipleObjects 的后续调用不会返回。 在线程上次检查队列) 之前收到的现有未读输入 (将被忽略。
函数修改某些类型的同步对象的状态。 仅针对其信号状态导致函数返回的对象或对象进行修改。 例如,信号量对象的计数将减少 1。 有关详细信息,请参阅各个同步对象的文档。
MsgWaitForMultipleObjects 函数可以指定 pHandles 数组中以下任何对象类型的句柄:
- 更改通知
- 控制台输入
- 事件
- 内存资源通知
- Mutex
- 进程
- Semaphore
- 线程
- 可等待计时器
要求
最低受支持的客户端 | Windows XP [仅限桌面应用] |
最低受支持的服务器 | Windows Server 2003 [仅限桌面应用] |
目标平台 | Windows |
标头 | winuser.h (包括 Windows.h) |
Library | User32.lib |
DLL | User32.dll |