2

使用WaitForMultipleObjects(... /*bWaitAll=*/FALSE ...)该函数时,显然会修改导致它返回的第一个同步对象的状态。也就是说,如果你有(有)一个带信号的自动重置事件,并且返回值表明这个事件对象导致函数返回,那么它肯定已经被重置了。

但是,请考虑您有多个对象的情况 - 这里:

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

所以你只取回了第一个句柄,并且你不知道这个索引之后是否有任何事件已经发出信号。

对于状态被修改的对象,现在的问题是,如果多个对象在 WaitForMultipleObjects 返回时已发出信号,是只修改第一个的状态,还是所有已发出信号的对象都已重置?

文档确实指出:

该函数修改某些类型的同步对象的状态。修改仅针对其信号状态导致函数返回的一个或多个对象。

所以这表明多个对象确实有可能修改它们的状态。然而,这与声明略有矛盾:

...此函数按从索引 0 开始的顺序检查数组中的句柄,直到其中一个对象发出信号。...

此外,这意味着不可能将此功能与多个同步对象(如自动重置事件、信号量等)一起使用,这些对象的状态已被修改,因为您总是会丢失信息。


我在“多个句柄时 WaitForMultipleObjects 的行为......”的答案中找到了一个声明,其他人会得出结论(从那里的评论):

WaitForMultipleObjects() 从 0 开始扫描句柄数组,并在找到信号句柄后立即返回。只有第一个找到的句柄被重置为无信号状态;其他的都没有动。– user82238 / 2009-03-25 19:27

但想重新询问并可能明确确认这一点。


CodeGuru上也有一个有趣的讨论,这似乎并没有说明这一点。

4

1 回答 1

2

好。瓦达知道。

来自Raymond Chen的评论:

如果等待一个事件,则仅修改该事件。如果等待所有事件,则所有事件都被修改。这就是文档中“对象或对象”的含义。如果 wait-any 是单数,如果 wait-all 是复数。– 雷蒙德陈

这将匹配文档,在包含“对象或对象”的段落之前,在相同的Remarks子标题下,我们发现

当 bWaitAll 为 TRUE 时,只有当所有对象的状态都设置为 signaled 时,函数的等待操作才完成。在所有对象的状态都设置为已发出信号之前,该函数不会修改指定对象的状态

所以要回答这个问题,如下:如果bWaitAll==FALSE只有一个对象(报告的那个是返回的索引)的状态发生了变化。

于 2014-04-02T17:46:25.593 回答