views:

111

answers:

5

When should we use mutex and when should we use semaphore ?

+9  A: 

A mutex is a mutual exclusion semaphore, a special variant of a semaphore that only allows one locker at a time and whose ownership restrictions may be more stringent than a normal semaphore.

In other words, it's equivalent to a normal counting semaphore with a count of one and the requirement that it can only be released by the same thread that locked it.

A semaphore, on the other hand, has a count and can be locked by that many lockers concurrently. And it may not have a requirement that it be released by the same thread that claimed it (but, if not, you have to carefully track who currently has responsibility for it, much like allocated memory).

So, if you have a number of instances of a resource (say three tape drives), you could use a semaphore with a count of 3. Note that this doesn't tell you which of those tape drives you have, just that you have a certain number.

Also with semaphores, it's possible for a single locker to lock multiple instances of a resource, such as for a tape-to-tape copy. If you have one resource (say a memory location that you don't want to corrupt), a mutex is more suitable.

Equivalent operations are:

Counting semaphore          Mutual exclusion semaphore
--------------------------  --------------------------
  Claim/decrease (P)                  Lock
  Release/increase (V)                Unlock

Aside: in case you've ever wondered at the bizarre letters used for claiming and releasing semaphores, it's because the inventor was Dutch. Probeer te verlagen means to try and decrease while verhogen means to increase.

paxdiablo
Okay, I came across binary semaphore too. When should we need to go in for binary semaphore and when should we use mutex ?
S.Man
Conceptually, a binary semaphore _is_ a mutex, and it's equivalent to a normal semaphore with a one-count. There may be differences in _implementations_ of the concept such as efficiency, or ownership of the resource (can be released by someone other than the claimer, which I don't agree with BTW - a resource should only be releasable by the thread that claimed it).
paxdiablo
Another potential implementation difference is the recursive mutex. Because there's only one resource, a single thread may be allowed to lock it multiple times (as long as it releases it that many times as well). This isn't so easy with a multiple-instance resource since you may not know whether the thread wants to claim _another_ instance or the _same_ instance again.
paxdiablo
Recursive mutex are evil, they show that the ressource handling is not properly mastered.
tristopia
They solve a specific problem. The fact that the problem they solve is people who don't _quite_ grok mutexes, should in no way belittle the solution :-)
paxdiablo
A mutex is totally different from a binary semaphore. Sorry but this definition is wrong
Peer Stritzinger
A: 

As was pointed out, a semaphore with a count of one is the same thing as a 'binary' semaphore which is the same thing as a mutex.

The main things I've seen semaphores with a count greater than one used for is producer/consumer situations in which you have a queue of a certain fixed size.

You have two semaphores then. The first semaphore is initially set to be the number of items in the queue and the second semaphore is set to 0. The producer does a P operation on the first semaphore, adds to the queue. and does a V operation on the second. The consumer does a P operation on the second semaphore, removes from the queue, and then does a V operation on the first.

In this way the producer is blocked whenever it fills the queue, and the consumer is blocked whenever the queue is empty.

Omnifarious
+2  A: 

While @opaxdiablo answer is totally correct I would like to point out that the usage scenario of both things is quite different. The mutex is used for protecting parts of code from running concurrently, semaphores are used for one thread to signal another thread to run.

/* Task 1 */
pthread_mutex_lock(mutex_thing);
    // Safely use shared resource
pthread_mutex_unlock(mutex_thing);



/* Task 2 */
pthread_mutex_lock(mutex_thing);
   // Safely use shared resource
pthread_mutex_lock(mutex_thing);

The mutex scenario is different

/* Task 1 - Producer */
sema_post(&sem);   // Send the signal

/* Task 2 - Consumer */
sema_wait(&sem);   // Wait for signal

See http://www.netrino.com/node/202 for further explanations

tristopia
You're right. Even if you are using a semaphore with a count of one, you are implying something about what you're doing than if you used a mutex.
Omnifarious
I'm not sure I agree with that, though I don't _disagree_ so vehemently that I'll downvote you :-) You say that the usage pattern of semaphores is to notify threads but that's exactly what mutexes do when there's another thread waiting on it, and exactly what semaphores _don't_ when there's no threads in `sema_wait` :-) In my opinion, they're _both_ about resources and the notification handed to other threads is a side-effect (very important, performance-wise) of the protection.
paxdiablo
A: 

See "The Toilet Example" - http://pheatt.emporia.edu/courses/2010/cs557f10/hand07/Mutex%20vs_%20Semaphore.htm:

Mutex:

Is a key to a toilet. One person can have the key - occupy the toilet - at the time. When finished, the person gives (frees) the key to the next person in the queue.

Officially: "Mutexes are typically used to serialise access to a section of re-entrant code that cannot be executed concurrently by more than one thread. A mutex object only allows one thread into a controlled section, forcing other threads which attempt to gain access to that section to wait until the first thread has exited from that section." Ref: Symbian Developer Library

(A mutex is really a semaphore with value 1.)

Semaphore:

Is the number of free identical toilet keys. Example, say we have four toilets with identical locks and keys. The semaphore count - the count of keys - is set to 4 at beginning (all four toilets are free), then the count value is decremented as people are coming in. If all toilets are full, ie. there are no free keys left, the semaphore count is 0. Now, when eq. one person leaves the toilet, semaphore is increased to 1 (one free key), and given to the next person in the queue.

Officially: "A semaphore restricts the number of simultaneous users of a shared resource up to a maximum number. Threads can request access to the resource (decrementing the semaphore), and can signal that they have finished using the resource (incrementing the semaphore)." Ref: Symbian Developer Library

fornwall
A: 

It is very important to understand that a mutex is not a semaphore with count 1!

This is the reason there are things like binary semaphores (which are really semaphores with count 1).

The difference between a Mutex and a Binary-Semaphore is the principle of ownership:

A mutex is acquired by a task and therefore must also be released by the same task. This makes it possible to fix several problems with binary semaphores (Accidential release, recursive deadlock and priority inversion).

Caveat: I wrote "makes it possible", if and how these problems are fixed is up to the OS implementation.

Because the mutex is has to be released by the same task it is not very good for synchronization of tasks. But if combined with condition variables you get very powerful building blocks for building all kinds of ipc primitives.

So my recommendation is: if you got cleanly implemented mutexes and condition variables (like with POSIX pthreads) use these.

Use semaphores only if they fit exactly to the problem you are trying to solve, don't try to build other primitives (e.g. rw-locks out of semaphores, use mutexes and condition variables for these)

There is a lot of misunderstanding mutexes and semaphores. The best explanation I found so far is in this 3-Part article:

Mutex vs. Semaphores – Part 1: Semaphores

Mutex vs. Semaphores – Part 2: The Mutex

Mutex vs. Semaphores – Part 3 (final part): Mutual Exclusion Problems

Peer Stritzinger
The urls to this site contain funky characters and do not work therefore... I'm working on it
Peer Stritzinger
Fixed the unicode characters in the urs, links now work.
Peer Stritzinger