我正在寻找一种没有副作用的方法。
理想情况下,以下代码可以解决这个问题:
long currentCount = 0;
::ReleaseSemaphore(h, 0, ¤tCount);
但不幸的是,0不允许作为lReleaseCount的值,因此调用返回FALSE。
答案 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内部结构。