【发布时间】:2014-04-02 14:20:27
【问题描述】:
当使用WaitForMultipleObjects(... /*bWaitAll=*/FALSE ...) 时,该函数显然会修改导致它返回的第一个同步对象的状态。也就是说,如果您有(有)信号自动重置event,并且返回值表明 this 事件对象导致函数返回,那么它肯定已被重置。
但是,请考虑您有 多个 对象的情况 - 此处:
当
bWaitAll为FALSE时,该函数检查数组中的句柄 从索引 0 开始,直到其中一个对象发出信号。 如果多个对象变为信号,该函数返回的索引 数组中的第一个句柄,其对象被发出信号。
所以你只取回了第一个句柄,并且你不知道这个索引之后是否有任何事件已经发出信号。
对于状态已修改的对象,现在的问题是,如果在 WaitForMultipleObjects 返回时已发出多个对象的信号,则只会修改第一个的状态, 还是将所有已发出信号的对象重置了吗?
文档确实说明了:
函数修改某些类型同步的状态 对象。修改只发生在对象或对象 信号状态导致函数返回。
因此这表明多个对象确实有可能修改其状态。然而,这有点与陈述相矛盾:
... 这个函数检查数组中的句柄 从索引 0 开始,直到其中一个对象发出信号。 ...
此外,这意味着不可能将此函数与多个状态已修改的同步对象(如自动重置事件、信号量等)一起使用,因为您总是会丢失信息。
我在this answer to "Behavior of WaitForMultipleObjects when multiple handles..." 中发现了一个声明,其他人会得出结论(从那里的评论):
WaitForMultipleObjects() 从 0 开始扫描句柄数组并 一旦找到带信号的句柄就返回。只有第一个发现 句柄被重置为无信号状态;其他的都没有动。 – user82238 / 2009 年 3 月 25 日 19:27
但想再次询问并可能明确确认这一点。
还有一个interesting discussion over at CodeGuru,似乎对此没有任何解释。
【问题讨论】:
-
我问了同样的问题:stackoverflow.com/questions/9776218/… 但答案包括相同的模棱两可的文档行...
-
@japreiss - 实际上本质上是重复的,字数更少,链接也更少。你为什么接受这个答案?如果你问我,它似乎没有回答任何问题:-)
-
我想我将“返回数组中第一个句柄的索引,其对象发出信号”暗示第一个句柄是“发出信号的对象状态导致函数返回”。另外,
WaitForMultipleObjects如果不这样做,那将几乎毫无用处。 -
但是你是对的——它本质上是模棱两可的。微软应该修复文档。
-
如果等待一个事件,那么只有那个事件被修改。如果等待所有事件,则所有事件都被修改。这就是文档中“对象或对象”的含义。如果 wait-any 是单数,如果 wait-all 是复数。
标签: c++ winapi visual-c++ waitformultipleobjects