如何从CSemaphore获得当前计数?

How do you get the current count from CSemaphore?

本文关键字:CSemaphore      更新时间:2023-10-16

我正在调试一个多线程程序,该程序使用CSemaphore来限制缓冲区的大小。

如何从这个类中获得信号量计数器的当前值?它似乎不能从它的任何成员直接访问,我似乎也找不到任何函数可以给我它

您不应该关心-这是一个信号量,而不是线程共享计数器。

也就是说,您可能会滥用ReleaseSemaphore API的lpPreviousCount输出参数
BOOL WINAPI ReleaseSemaphore(
  __in       HANDLE hSemaphore,
  __in       LONG lReleaseCount,
  __out_opt  LPLONG lpPreviousCount
);

的想法:
CSemaphore &mySemaphore = /*initialized from somewhere*/;
HANDLE hsem = (HANDLE) mySemaphore; // http://msdn.microsoft.com/en-us/library/f5zcch25.aspx
LONG peeked_count;
::ReleaseSemaphore(hsem, 1 /*can't be 0, sorry!*/, &peeked_count);

请注意,不幸的是,您必须实际释放信号量(lReleaseCount必须>0)

这并不容易。如果您真的想这样做,我所能想到的就是尽可能多地手动锁定信号量,直到锁定失败,没有超时,然后立即解锁。您还必须记住最大计数。例如,未测试的代码:

int max_count = 5;
CSemaphore sem (max_count, max_count);
/*...*/
int count = 0;
while (sem.Lock (0))
  ++count;
for (int i = 0; i != count; ++i)
  sem.Unlock(count);
std::cout << "the lock count is " << (max_count - count);
编辑:

看了她的解决方案后,我认为更好的解决方案是两者结合:

int max_count = 5;
CSemaphore sem (max_count, max_count);
if (sem.Lock(0))
{
  LONG peeked_count;
  ::ReleaseSemaphore(hsem, 1 /*can't be 0, sorry!*/, &peeked_count);
  /* peeked_count has the count */
}
else
{
  /* I do not think it is safe to release the semaphore even if just for debugging. */
  /* max_count has the count */
}