【问题标题】:How do you get the current count from CSemaphore?您如何从 CSemaphore 获得当前计数?
【发布时间】:2011-10-30 12:05:36
【问题描述】:

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

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

【问题讨论】:

  • 禁止知识。因为如果你能得到它,你有时会得到错误的值。不要乱穿线比赛,他们会吃掉你。
  • @Hans:忘掉量子计算吧,这就是量子编程!
  • 为什么不直接跟踪事件以手动调试和计数?您甚至可以以“类似 CSV”的格式进行跟踪并粘贴到 excel 中,这样您就可以做一些公式。

标签: c++ multithreading visual-c++ mfc semaphore


【解决方案1】:

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

也就是说,您可能会滥用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)

【讨论】:

  • 谢谢。通常我不在乎计数器是什么,但我在调试时会这样做!我真正想做的是在计数器为 0 或最大值时触发断点,但我想这不是东东要做的事情。我想我将不得不在信号量旁边添加一个int 计数器,并在信号量被锁定/释放的任何地方手动增加/减少它:-/
【解决方案2】:

这并不容易。如果你真的想这样做,我能想到的就是尽可能多次手动锁定信号量,直到锁定失败,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);

编辑:

看到sehe's solution后,我认为更好的解决方案是两者结合:

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 */
}

【讨论】:

  • 哇。这假设信号量是单线程使用的。破坏信号量的全部目的。这段代码可以很好地作为复杂竞争条件纠缠网络的高度炮制示例?
  • @sehe,无论如何,在您打印或对其进行任何操作之前,您获得的任何计数都可能无效。我只是假设应用程序是这样的,信号量的所有其他用途都会阻塞,直到他们可以获取它。
  • 除非你使用Release API返回之前的计数;这是一个明确定义的时刻的原子计数。没有种族。
  • @sehe:我想我现在明白你的意思了。但除非应用程序中的获取/释放计数在某种程度上是不对称的,否则它应该也能正常工作,并在 sem.Lock(0) 返回 false 的时间点给出获取计数。
猜你喜欢
  • 2010-09-22
  • 2014-09-10
  • 2016-05-03
  • 2010-12-24
  • 2010-10-15
  • 2014-12-04
  • 1970-01-01
  • 2010-09-26
  • 2012-02-09
相关资源
最近更新 更多