Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should I use semaphores?

When would one use semaphores ?

Only example I can think of is limiting the number of threads accessing the same data/code simultaneously...

Any other scenarios in which semaphores would be the best solution ?

like image 773
Yochai Timmer Avatar asked Apr 08 '11 20:04

Yochai Timmer


People also ask

When should semaphores be used?

Semaphores are typically used in one of two ways: To control access to a shared device between tasks. A printer is a good example. You don't want 2 tasks sending to the printer at once, so you create a binary semaphore to control printer access.

Why do we need semaphore?

The main aim of using a semaphore is process synchronization and access control for a common resource in a concurrent environment. The initial value of a semaphore depends on the problem at hand. Usually, we use the number of resources available as the initial value.

Which is better semaphore or mutex?

If you have number of instances for resource it is better to use Binary semaphore. If you have single instance for resource it is better to use mutex.

Which 3 kind of problem can be solved using semaphores?

Semaphores are used to solve a problem of race condition, mutual exclusion, process synchronization.


2 Answers

Connection Pools.

I.e. you have 20 connections and 150 threads. In that case you would have a semaphore to control access to the 20 connections.

like image 41
Soraz Avatar answered Oct 05 '22 00:10

Soraz


Semaphores might be appropriate for signaling between processes. For multithreaded programming, semaphores should be avoided. If you need exclusive access to a resource, use mutex. If you need to wait for a signal, use condition variable.

Even the most often mentioned case of a resource pool can be implemented simpler and safer with a condition variable than with a semaphore. Let's look at this case. A naive implementation with a semaphore would look like (pseudocode):

wait for semaphore to open
take a resource out of the pool
use the resource
put it back to the pool
open the semaphore for one more thread

The first problem is that semaphore does not protect the pool from being accessed by several threads. So, another protection is required. Let it be a lock:

wait for semaphore to open
acquire the lock for the pool
take a resource out of the pool
release the lock
use the resource
acquire the lock
put the resource back to the pool
release the lock
open the semaphore for one more thread

Additional measures need to be taken to ensure the pool is not empty when accessed. Technically it is possible to access the pool bypassing the semaphore, but it would break resource availability guarantees for the acquisition procedure above. So the pool should be only accessed via that procedure.

So far so good, but what if a thread does not want to wait passively for a resource? Can non-blocking resource acquisition be supported? It's easy if the semaphore itself supports non-blocking acquisition; otherwise (e.g. on Windows) this will be problematic. The semaphore cannot be bypassed, because it would break the blocking case. Passing through the semaphore only if the pool is not empty may lead to a deadlock if done under the lock, but as soon as the lock is released, the result of the check for emptiness becomes useless. It is probably doable (I did not try), but surely leads to significant additional complexity.

With condition variable, this is solved easily. Here is the pseudocode with blocking acquisition:

acquire the lock
while the resource pool is empty,
    wait for condition variable to be signaled
take a resource out of the pool
release the lock
use the resource
acquire the lock
put the resource back to the pool
release the lock
signal the condition variable

And in this case there is no problem to add non-blocking acquisition:

acquire the lock
if the resource pool is not empty,
    take a resource out of the pool
release the lock
if the pool was empty, return

As you may see, it does not even need to access condition variable, and makes no harm to the blocking case. To me, it's clearly superior to the use of semaphore.

like image 107
Alexey Kukanov Avatar answered Oct 05 '22 00:10

Alexey Kukanov