I am trying to debug a multi-thr开发者_开发技巧eaded 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.
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)
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 */
}
精彩评论