【发布时间】:2011-02-14 19:22:08
【问题描述】:
我正在寻找一种没有副作用的方法。
理想情况下,以下代码可以解决问题:
long currentCount = 0;
::ReleaseSemaphore(h, 0, ¤tCount);
但遗憾的是,lReleaseCount 的值不允许为 0,因此调用返回 FALSE。
【问题讨论】:
我正在寻找一种没有副作用的方法。
理想情况下,以下代码可以解决问题:
long currentCount = 0;
::ReleaseSemaphore(h, 0, ¤tCount);
但遗憾的是,lReleaseCount 的值不允许为 0,因此调用返回 FALSE。
【问题讨论】:
没有诸如 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,这将是一个竞争条件。
【讨论】:
如果您希望该值用于外部监控(正如您在评论中所建议的那样),那么在调用 ReleaseSemaphore() 或恕我直言之后使用之前的值,一个更好的解决方案是您实现自己的“联锁”计数器,除了你的信号量;然后你就有了你的监控计数,并且可以以任何你喜欢的方式访问它......只是不要用它来查看你是否可以“输入”信号量......
正如 Chris 所说,您无法获得当前计数,因为它可能一直在变化。
【讨论】:
sysinternals 工具 Process Explorer 可以显示 win32 句柄的内部结构,包括信号量及其当前/最大计数。对于调试来说已经足够了,但对于自动监控来说不是那么有用。
如果 Process Explorer 可以做到,您可能也可以...但可能需要深入了解 Windows 内部结构。
【讨论】:
这可能有点太晚了,但我认为 NtQuerySemaphore() 可能是你想看看的。
【讨论】: