给定:我用自动重置事件填充一个句柄数组,并将其传递给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.
}
答案 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