При каких обстоятельствах критический раздел Windows может иметь отрицательный счетчик блокировок? - PullRequest
8 голосов
/ 14 сентября 2011

Существуют ли обстоятельства, при которых поле LockCount структуры RTL_CRITICAL_SECTION в Windows может на законных основаниях быть отрицательным?

Мы отслеживаем ОЧЕНЬ неуловимый сбой, и одним из симптомов, который мы видим, является CS с отрицательным значением LockCount. В момент сбоя счетчик равен -6, но обычно он равен -1, -2 и т. Д.

Прежде чем идти за этим, предполагая, что это очень плохо, я просто хочу убедиться, что это предположение верно. Я не могу найти почти никакой информации о внутренней работе RTL_CRITICAL_SECTION.

Ответы [ 2 ]

12 голосов
/ 14 сентября 2011

Отрицательное число блокировок - нормальное поведение в некоторых версиях Windows. Обратите внимание, что значение этого поля изменилось за время существования Windows (см. Ниже).

Интерпретация этих закрытых полей - дело сложное, и вы можете извлечь выгоду из использования специальных инструментов отладки критических секций.

Например, см. Эту статью MSDN , которая дает некоторые подробности. В частности, я думаю, что это показывает, почему значение -6 вполне вероятно.

Некоторые соответствующие выдержки:

Критические разделы могут отображаться в пользовательском режиме различными способами. Точное значение каждого поля зависит от версии используемой вами версии Microsoft Windows.

......

В Microsoft Windows 2000 и Windows XP поле LockCount указывает количество раз, которое какой-либо поток вызывал подпрограмму EnterCriticalSection для этого критического раздела, минус один. Это поле начинается с -1 для разблокированного критического раздела. Каждый вызов EnterCriticalSection увеличивает это значение; каждый вызов LeaveCriticalSection уменьшает его. Например, если LockCount равен 5, этот критический раздел заблокирован, один поток получил его, и пять дополнительных потоков ожидают эту блокировку.

......

В Microsoft Windows Server 2003 с пакетом обновления 1 и более поздних версиях В Windows поле LockCount анализируется следующим образом:

  • Самый младший бит показывает состояние блокировки. Если этот бит равен 0, критический раздел заблокирован; если это 1, критическая секция не заблокирована.
  • Следующий бит показывает, проснулся ли поток для этой блокировки. Если этот бит равен 0, тогда для этой блокировки был пробужден поток; если это 1, ни одна нить не проснулась.
  • Остальные биты являются единицами числа потоков в ожидании блокировки.

Далее объясняется, как интерпретировать счетчик блокировок -22. Итак, в целом, это сложнее, чем вы думаете!

5 голосов
/ 14 сентября 2011

С здесь , это объяснение части:

LockCount Это самое важное поле в критическом разделе.Инициализируется значением -1;значение 0 или больше указывает, что критический раздел хранится или принадлежит.Если оно не равно -1, поле OwningThread (это поле неправильно определено в WINNT.H - оно должно быть DWORD вместо HANDLE) содержит идентификатор потока, которому принадлежит этот критический раздел.Дельта между этим полем и значением (RecursionCount -1) указывает, сколько дополнительных потоков ожидает получения критической секции.

...