Есть ли способ узнать текущее количество семафора win32?

Я ищу способ без побочных эффектов.

в идеале, следующий код будет делать трюк:

long currentCount = 0;  
::ReleaseSemaphore(h, 0, &currentCount);  

но, к сожалению, 0 не допускается в качестве значения lReleaseCount, поэтому вызов возвращает FALSE.

4 ответов


Если вы хотите, чтобы это значение для внешнего мониторинга (как вы предлагаете в своем комментарии), то либо используйте Предыдущее значение после вызова ReleaseSemaphore() или IMHO лучшим решением является то, что вы реализуете свой собственный "блокируемый" счетчик в дополнение к семафору; затем у вас есть счетчик мониторинга и вы можете получить к нему доступ любым способом... Просто не используйте его как способ увидеть, можете ли вы "войти" в семафор...

Как правильно говорит Крис, вы не можете получить текущий счет, как он есть потенциально всегда меняется.


Это может быть слишком поздно, но я думаю, что NtQuerySemaphore (), вероятно, то, что вы хотите посмотреть.


нет такой вещи, как "текущий счетчик" семафора Win32 - вот почему вы не можете его получить.

Я имею в виду, очевидно, в какой-то момент времени счетчик семафора будет иметь некоторое значение, но с точки зрения потока, если он не предпримет действий для увеличения или уменьшения количества семафоров, другой поток может сделать любой ответ, полученный полностью недействительным в момент его вычисления.

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


очевидное "обойти" можно было бы сделать что-то вроде

LONG count = 0;
if( WAIT_OBJECT_0 == WaitForSingleObject(hSemaphore,0L))
{
  // Semaphores count is at least one.
  ReleaseSemaphore(hSemaphore,1,&count);
}

почему это лучше? Я не уверен. Но, возможно, есть возможность сделать что-то значимое между ожиданием и выпуском, что было бы условием гонки, если ReleaseSemaphore было разрешено выпустить 0.


инструмент Sysinternals Process Explorer может отображать внутренние дескрипторы win32, включая семафоры и их текущее/максимальное количество. Достаточно хорошо для отладки, но не так полезно для автоматического мониторинга.

Если Process Explorer может это сделать, вы, вероятно, тоже можете ... но это, вероятно, потребует глубокого знания внутренних компонентов windows.