Search code examples
cpthreadssemaphore

Number of threads waiting for semaphore


So my problem is simple, I need to know how many threads are waiting for the semaphore(are queued). Initially I thought sem_getvalue would return a negative number showing the number of threads blocked by the semaphore but it only goes down to 0 and stays there. I also tried to declare a global variable like int waiting and incrementing it before calling sem_wait with waiting++ and decrementing it after the call but it seems like this solution is not working(by which I am baffled because I thought incrementing and decrementing won't cause race condition). I have looked at the semaphore.h but none of the functions seem to do what I want. Writing here, I came up with an imperfect solution of declaring a second semaphore and initializing it with 0 then calling sem_post on it before the actual sem_wait and a wait after the actual wait. Haven't tested whether it works but even if it does it seems a little hacky a not very nice!


Solution

  • Without getting into why you have a lot of threads waiting on a semaphore, one way to solve this is what you already have tried, having a counter. This counter has to be *atomic*, or do something like:

    pthread_mutex_t wait_m = PTHREAD_MUTEX_INITIALIZER;
    int wait_counter = 0;
    
    void inc_wait_counter() 
    {
        pthread_mutex_lock(&wait_m);
        wait_counter ++;
        pthread_mutex_unlock(&wait_m);
    
    }
    
    void dec_wait_counter() 
    {
        pthread_mutex_lock(&wait_m);
        wait_counter --;
        pthread_mutex_unlock(&wait_m);
    
    }
    
    int get_wait_counter()
    {
        /* No need to lock here for only reading wait_counter */
        return wait_counter;
    }
    

    Then just something like:

    inc_wait_counter();
    sem_wait(...);
    dec_wait_counter();
    

    NOTE: Using atomic integers instead, I suggest to check: How to do an atomic increment and fetch in C?