Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check the state of a semaphore

Tags:

I want to check the state of a Semaphore to see if it is signalled or not (so if t is signalled, I can release it). How can I do this?

EDIT1:

I have two threads, one would wait on semaphore and the other should release a Semaphore. The problem is that the second thread may call Release() several times when the first thread is not waiting on it. So the second thread should detect that if it calls Release() it generate any error or not (it generate an error if you try to release a semaphore if nobody waiting on it). How can I do this? I know that I can use a flag to do this, but it is ugly. Is there any better way?

like image 680
mans Avatar asked Sep 07 '11 08:09

mans


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.

What is the value of a semaphore?

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.

How do you access semaphores?

To release or signal a semaphore, we use the sem_post function: int sem_post(sem_t *sem); A semaphore is initialised by using sem_init(for processes or threads) or sem_open (for IPC). sem_init(sem_t *sem, int pshared, unsigned int value);

What will happen if the value of the counting semaphore becomes 0?

If the value of pshared is zero, then the semaphore cannot be shared between processes. If the value of pshared is nonzero, then the semaphore can be shared between processes. Multiple threads must not initialize the same semaphore. A semaphore must not be reinitialized while other threads might be using the semaphore.


Video Answer


1 Answers

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. This, of course, could change the state of the semaphore which makes it cumbersome to use.

Another reason why this trick will not help you is because a semaphore is said to be signaled when at least one count is available. It sounds like you want to know when the semaphore has all counts available. The Semaphore class does not have that exact ability. You can use the return value from Release to infer what the count is, but that causes the semaphore to change its state and, of course, it will still throw an exception if the semaphore already had all counts available prior to making the call.

What we need is a semaphore with a release operation that does not throw. This is not terribly difficult. The TryRelease method below will return true if a count became available or false if the semaphore was already at the maximumCount. Either way it will never throw an exception.

public class Semaphore
{
    private int count = 0;
    private int limit = 0;
    private object locker = new object();

    public Semaphore(int initialCount, int maximumCount)
    {
        count = initialCount;
        limit = maximumCount;
    }

    public void Wait()
    {
        lock (locker)
        {
            while (count == 0) 
            {
                Monitor.Wait(locker);
            }
            count--;
        }
    }

    public bool TryRelease()
    {
        lock (locker)
        {
            if (count < limit)
            {
                count++;
                Monitor.PulseAll(locker);
                return true;
            }
            return false;
        }
    }
}
like image 92
Brian Gideon Avatar answered Oct 20 '22 12:10

Brian Gideon