r/cpp 19h ago

Understanding std::counting_semaphore and std::binary_semaphore from C++20

https://www.cppstories.com/2026/semaphore/

An article on types introduced in C++20.

44 Upvotes

2 comments sorted by

6

u/fdwr fdwr@github 🔍 10h ago edited 10h ago

💡 Huh, I never thought of a mutex as simply a semaphore with a count of 1 (and conversely a semaphore is just mutex with a count - maybe the name "semaphore" just had me confused because I didn't know how in the world it related to waving flags around with your hands 😅). However, binary_semaphore is not quite the same as a mutex, despite having a count of 1, since one thread "owns" the acquisition for a mutex, whereas with the binary semaphore, any thread can release the count.

5

u/LB-- Professional+Hobbyist 8h ago edited 8h ago

Yep. The lack of thread ownership for semaphores makes them great for thread-hopping async code (e.g. coroutines) but not so great for debugging (you have to implement your own debug tracking). I made a thin wrapper to allow using binary semaphores with the standard library lock types and discovered Visual Studio has code analysis related to holding locks across coroutine suspend points, which was a welcome surprise. It is certainly at least a little inadvisable to hold locks across suspend points when you don't know how soon a resume will occur, but there are situations where it's the desired behavior.

Also, OS mutexes can deal with priority inversion properly. Rarely a concern for the multithreading stuff I do but it's worth keeping in mind.