2013-05-08 4 views
1

У меня 5 темы (В системе многоядерной), которые одновременно ждать:Почему WaitForMultipleObjectsEx приобретает мьютекс во время APC?

  1. Мьютекса М быть приобретены
  2. События Е, чтобы получить сигнал

Я использую WaitForMultipleObjectsEx(..., TRUE, INFINITE, TRUE) так потоки используют БТР.
Обратите внимание, что APCs не использовать/коснуться/изменить/соблюдать мьютекс или событие в любом случае.

Я использую Visual Studio вместе с Process Hacker для отладки, и я свидетелем странного явления:
Часто нить, которая должна для запуска (назовем это нить А) все еще ждет на два объекты.

я говорю «должен работать», потому что:

  1. Я много раз проверены (в том числе с помощью Process Hacker), что E действительно находится в сигнальном состоянии
  2. Ни один другой поток не приобрел право собственности на М . в самом деле, другие нити также ожидает получения M.

тем не менее, согласно способу Hacker (который использует NtQueryMutant to retrieve the count), во время таких сценариев, M имеет абсурдно низкое значение «Count», например -618.

Конечно, я не забываю позвонить ReleaseMutex (да, я также проверяю возвращаемое значение); действительно, как только кто-то позже обретает мьютекс, граф увеличивает резерв.

Таким образом, возникает вопрос: если 3 из 4 других нитей спать, то чем занимается последняя нить (B)?

Ответ: B - , выполняющий APC внутри звонка WaitForMultipleObjectsEx.
Независимо от того, как далеко я «шаг» через B в Visual Studio (даже весь путь обратно RtlDispatchAPC) ни из других потоков просыпаются.
Это только после, что APC закончил выполнение, чтобы всякий поток просыпался!

Я нахожу это довольно странно, WaitForMultipleObjectEx's documentation says:

Когда bWaitAll является TRUE, операция ожидания работы функции завершается только тогда, когда состояние всех объектов было установлено в сигнальное. Функция не изменяет состояния указанных объектов, пока не будут установлены состояния всех объектов. Например, мьютекс может быть сигнализирован, но нить не получает право собственности, пока состояния других объектов также не будут установлены на сигнализацию. Тем временем, некоторые другие потоки могут получить право собственности на мьютекс, тем самым установив свое состояние в несогласованное.

Неверная документация, или это ошибка с моей стороны?

Почему WaitForMultipleObjectsEx приобретает мьютекс во время выполнения БТР, даже если он знает он никогда не будет приобретать мьютекс в любом случае (поскольку выполнение БТР предполагает, что будет возвращать WAIT_IO_COMPLETE, никогда не эквайринг мьютекса)?

+0

Большой отрицательный счет на мьютексе подразумевает, что тот же поток приобрел его несколько раз, возможно, рекурсивным образом. Почему это может произойти? Ожидают ли ваши БТР тревожные ожидания? – arx

+0

@arx: Это смешная вещь - мои APC * не делают * делать тревожные ожидания. Максимальная вложенность APC равна 1. (Я проверил это как в коде, так и внутри Process Hacker). – Mehrdad

ответ

0

Я не могу комментировать, поэтому я использую ответ ...

Вы не показывают никакого кода, но не должен АРС вызвать WaitForMultipleObjectsEx возвращение с WAIT_IO_COMPLETION кода в потоке, который работает ??