A canonical example of using a counting semaphore instead of a binary mutex is when you have a limited amount of available resources: a) interchangeable and b) more than one.
For example, if you want a maximum of 10 readers to be able to access the database right away, you can use a counted semaphore initialized to 10 to restrict access to the resource. Each reader should get a semaphore before accessing the resource, reducing the available score. When the counter reaches 0 (i.e. 10 readers have access and use the database), all other readers are blocked. As soon as the reader finishes work, they reset the number of semaphores to one to indicate that they no longer use the resource, and another reader can now get the semaphore lock and access them instead.
However, the calculated semaphore, like all other synchronization primitives, has many use cases, and this is just a question outside the box. You may find that many of the problems you use to solve with a mutex plus additional logic can be more easily and more simply implemented using a semaphore. A mutex is a subset of a semaphore, i.e. Everything that you can do with a mutex can be done with a semaphore (just set the count value to one), but there are things that can only be done with a semaphore that can't be done with just a mutex.
At the end of the day, any of the synchronization primitives is usually enough to do something (think of it as a "completion-completion" for thread synchronization to strengthen this word). Nevertheless, each of them is adapted to different applications, and although you can force you to bet with some setting and additional glue, it is possible that another synchronization primitive is better suited for work.
source share