Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to find out the current count of a win32 semaphore?

I'm looking for a way with no side effects.

Ideally, the following code would do the trick:

long currentCount = 0;  
::ReleaseSemaphore(h, 0, &currentCount);  

But unfortunately 0 is not allowed as the value of lReleaseCount, so the call returns FALSE.

like image 757
Benjamin Nitlehoo Avatar asked May 02 '10 17:05

Benjamin Nitlehoo


People also ask

Can you check the value of a semaphore?

The sem_getvalue() function retrieves the value of a named or unnamed semaphore. If the current value of the semaphore is zero and there are threads waiting on the semaphore, a negative value is returned. The absolute value of this negative value is the number of threads waiting on the semaphore.

How do you know what state a semaphore is in?

You can check to see if a Semaphore is signaled by calling WaitOne and passing a timeout value of 0 as a parameter. This will cause WaitOne to return immediately with a true or false value indicating whether the semaphore was signaled.

What is a semaphore value?

The value of the semaphore S is the number of units of the resource that are currently available. The P operation wastes time or sleeps until a resource protected by the semaphore becomes available, at which time the resource is immediately claimed.

What are semaphores Windows?

The semaphore object is useful in controlling a shared resource that can support a limited number of users. It acts as a gate that limits the number of threads sharing the resource to a specified maximum number. For example, an application might place a limit on the number of windows that it creates.


3 Answers

If you want that value for external monitoring (as you suggest in your comment) then either use the previous value after a call to ReleaseSemaphore() or IMHO a better solution is that you implement your own 'interlocked' counter in addition to your semaphore; you then have your monitoring count and can access it in any way you like... Just don't use it as a way of seeing if you can 'enter' the semaphore...

As Chris rightly says, you can't obtain the current count as it is potentially always changing.

like image 54
Len Holgate Avatar answered Jan 04 '23 06:01

Len Holgate


This might be a little too late but I think NtQuerySemaphore() is probably what you want to take a look at.

like image 29
ȷ̇c Avatar answered Jan 04 '23 05:01

ȷ̇c


There is no such thing as a "current count" of a Win32 semaphore - which is why you can't get it.

I mean, patently, at some point of time the count on a semaphore will be some value, but from the point of view of a thread, unless it takes action to increase or decrease the semaphore count, another thread might make any answer retrieved entirely invalid the moment it is computed.

It is for this reason that windows api synchronization functions do not let you take the previous lock count without a side effect. The side effect guarantees that you have a valid window of opportunity to actually use the value in a meaningful way.


The obvious "work around" would be to do something like

LONG count = 0;
if( WAIT_OBJECT_0 == WaitForSingleObject(hSemaphore,0L))
{
  // Semaphores count is at least one.
  ReleaseSemaphore(hSemaphore,1,&count);
}

Why is this better? I'm not sure. But perhaps there is a possibility of doing something meaningful between waiting and releasing that would have been a race condition if ReleaseSemaphore was allowed to release 0.

like image 26
Chris Becke Avatar answered Jan 04 '23 06:01

Chris Becke