1

我有 5 个线程(在多核系统上)同时等待:

  1. 要获取的互斥锁 M
  2. 要发出信号的事件 E

我正在使用WaitForMultipleObjectsEx(..., TRUE, INFINITE, TRUE),因为线程使用 APC。
请注意,APC不会以任何方式使用/触摸/更改/观察互斥锁或事件。

我正在使用 Visual Studio 和Process Hacker进行调试,我正在目睹一个奇怪的现象:
通常,应该运行的线程(称为线程 A)仍在等待这两个对象。

我说“应该运行”是因为:

  1. 我已经多次验证(包括通过 Process Hacker)E 确实处于信号状态
  2. 没有其他线程获得 M 的所有权。实际上,还有3 个其他线程也在等待获得 M。

然而,根据 Process Hacker(用于NtQueryMutant检索计数)的说法,在这种情况下,M 的“计数”值低得离谱,例如 -618。

当然,我没有忘记调用ReleaseMutex(是的,我也在检查返回值);事实上,一旦有人后来获得了互斥锁,Count 就会重新增加。

所以这引出了一个问题:如果其他 4 个线程中有 3 个正在休眠,那么最后一个线程(B)在做什么?

答案是 B 正在调用中执行 APC 。无论我在 Visual Studio 中“逐步”通过 B 多远(甚至一直备份),其他线程都不会唤醒。 只有APC 完成执行后,才会唤醒任何线程!WaitForMultipleObjectsEx
RtlDispatchAPC

我觉得这很奇怪,WaitForMultipleObjectEx文档说

bWaitAllTRUE时,仅当所有对象的状态都设置为已发出信号时,函数的等待操作才完成。在所有对象的状态都设置为已发出信号之前,该函数不会修改指定对象的状态。例如,可以向互斥体发出信号,但在其他对象的状态也设置为已发出信号之前,线程不会获得所有权。与此同时,其他一些线程可能会获得互斥锁的所有权,从而将其状态设置为非信号。

文档是错误的,还是我的错误?

为什么WaitForMultipleObjectsEx在 APC 执行期间获取互斥锁,即使它知道无论如何它永远不会获取互斥锁(因为执行 APC 意味着它将返回WAIT_IO_COMPLETE,永远不会获取互斥锁)?

4

1 回答 1

0

我无法发表评论,所以我使用答案...

您没有显示任何代码,但 APC 不应该在正在运行的线程中触发带有 WAIT_IO_COMPLETION 代码的 WaitForMultipleObjectsEx 返回?

于 2013-05-09T10:05:30.333 回答