有没有办法找出win32信号量的当前计数?

时间:2010-05-02 17:34:12

标签: winapi semaphore

我正在寻找一种没有副作用的方法。

理想情况下,以下代码可以解决这个问题:

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

但不幸的是,0不允许作为lReleaseCount的值,因此调用返回FALSE。

4 个答案:

答案 0 :(得分:4)

如果您希望该值用于外部监控(正如您在评论中所建议的那样),那么在调用ReleaseSemaphore()或恕我直言之后使用前一个值更好的解决方案是您实现自己的'互锁'计数器除了你的信号量;然后你有你的监控计数,并可以任何你喜欢的方式访问它...只是不要用它来看看你是否可以'输入'信号量......

正如克里斯正确地说,你无法获得当前的数量,因为它可能总是在变化。

答案 1 :(得分:4)

这可能有点太晚了,但我认为NtQuerySemaphore()可能就是你要看的内容。

答案 2 :(得分:2)

没有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那将是一场竞争条件。

答案 3 :(得分:2)

sysinternals工具Process Explorer可以显示win32句柄的内部,包括信号量及其当前/最大计数。足够好用于调试但对自动监控不太有用。

如果Process Explorer可以做到,你可能也可以......但它可能需要深入了解windows内部结构。