当多个句柄同时发出信号时,WaitForMultipleObjects的行为

时间:2009-03-20 18:11:00

标签: multithreading winapi events

给定:我用自动重置事件填充一个句柄数组,并将其传递给WaitForMultipleObjects,bWaitAll = FALSE。

来自MSDN: “当bWaitAll为FALSE时,此函数按顺序检查数组中的句柄,从索引0开始,直到其中一个对象发出信号。如果多个对象变为信号,则该函数返回其对象已发出信号的数组中第一个句柄的索引。“

所以,现在如果多个对象发出信号,我将得到第一个的索引。我是否必须通过我的阵列循环以查看是否有其他人发出信号?

现在我有一个循环:

For ( ; ; )
{
WaitForMultipleObjects(…)
If  (not failed)
     Process object that called. 
     Remove the handle that signaled from the array.
     Compact the arrary.
}

4 个答案:

答案 0 :(得分:5)

是。另一种方法是你可以在每个句柄上做WaitForSingleObject(句柄,0),它会立即返回并指示它们是否有信号。

编辑:这是我的意思的样本伪代码:

ret = WaitForMultipleObjects()
if (ret >= WAIT_OBJECT_0 && ret < WAIT_OBJECT_0 + (count))
{
    firstSignaled = ret - WAIT_OBJECT_0;

    // handles[firstSignaled] guaranteed signalled!!

    for (i = firstSignaled + 1; i < count; i++)
    {
        if (WaitForSingleObject(handles[i], 0) == WAIT_OBJECT_0)
        {
           // handles[i] Signaled!
        }
    }
}

答案 1 :(得分:5)

  

所以,现在如果多个对象发出信号,我将得到第一个的索引。我必须循环吗?   虽然我的数组是否有其他信号发出信号?

为什么不回到Wait()?如果多个物体发出信号,当你回来时它们仍然会发出信号。当然,如果你在wait对象数组中有一个非常快速地触发第一个对象,它会使其他对象饿死;你所做的是按照射击频率在等待对象数组中命令你的对象,最少的是先发生。

顺便说一句,在你使用无穷的for()时,你可以使用goto。如果你真的没有离开循环,那么无条件的goto最恰当地表达你的意图。

答案 2 :(得分:3)

您可能拥有的另一个选项是使用RegisterWaitForSingleObject。我们的想法是在回调函数中标记辅助数组中事件的信号状态,然后发出一个主事件信号,该事件用于唤醒主线程(在主事件上调用WaitForSingleObject)。

显然,您必须注意确保辅助阵列受到主线程的访问保护,但它可以正常工作。

答案 3 :(得分:0)

仅重置结束等待的自动重置事件(其索引被返回)。如果等待超时,则不会重置任何事件。

CF https://blogs.msdn.microsoft.com/oldnewthing/20150409-00/?p=44273