如何从 CSemaphore 获取当前计数?

发布于 2024-11-30 04:29:57 字数 208 浏览 1 评论 0原文

我正在尝试调试使用 CSemaphore 限制缓冲区的大小。

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

I am trying to debug a multi-threaded program that uses CSemaphore to limit the size of a buffer.

How do you get the current value of the semaphore counter from this class? It doesn't seem to be directly accessed from any of its members, and I can't seem to find any functions that will give me it either.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

内心激荡 2024-12-07 04:29:57

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

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

You're not supposed to care - this is a semaphore, not thread-shared counter.

That said, you might abuse the ReleaseSemaphore API's lpPreviousCount output parameter

BOOL WINAPI ReleaseSemaphore(
  __in       HANDLE hSemaphore,
  __in       LONG lReleaseCount,
  __out_opt  LPLONG lpPreviousCount
);

The idea:

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);

Note that unfortunately you'll have to actually release the semaphore (lReleaseCount must be >0)

澉约 2024-12-07 04:29:57

这并不容易实现。如果你真的想这样做,我能想到的就是尝试尽可能多次手动锁定信号量,直到锁定失败,超时为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的解决方案,我认为更好的解决方案是两者的结合:

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

That is not easily possible. If you really want to do that, all I can think of doing is to try to lock the semaphore manually as many times as possible, until the locking fails, with 0 time-out, and unlocking immediately after that. You will also have to remember the max count. E.g., untested code:

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);

EDIT:

After seeing sehe's solution, I think a better solution would be combination of both:

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 */
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文