Search code examples
c++multithreadingc++20semaphorebinary-semaphore

C++20 binary semaphore goes over max


I don't understand the difference between counting semaphore and binary semaphore in C++20 (or there's a bug). I can understand the idea, but they both work the same, no difference. I can release the binary semaphore multiple times, then acquire multiple times and it doesn't block (despite that returned max value is 1).

#include <iostream>
#include <semaphore>

int main(int argc, char ** argv)
{
    std::binary_semaphore sem{0};
    std::cout << sem.max() << std::endl;
    
    sem.release();
    sem.release();
    
    sem.acquire();
    sem.acquire();

    return 0;
}

Compiled with: g++-11 -O0 -std=c++20 bin_semaphore.cpp -o sem.out

Out: 1 and returned.

I assume it should lock forever, but it doesn't. Can someone explain this behavior?


Solution

  • Semaphores, like much of C++, are not safe objects. In particular, nothing will error out just because you released the semaphore more times than its maximum counter value. That merely yields undefined behavior, so you can't do it, but nothing in the API is going to stop you.

    The behavior of your code became undefined when you released the semaphore more than its maximum counter variable. What happens next is irrelevant.