148

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

legends2k
  • 31,634
  • 25
  • 118
  • 222
Karthik Balaguru
  • 7,424
  • 7
  • 48
  • 65
  • 2
    possible duplicate of [What is mutex and semaphore in Java ? What is the main difference ?](http://stackoverflow.com/questions/771347/what-is-mutex-and-semaphore-in-java-what-is-the-main-difference) – Merlyn Morgan-Graham Oct 28 '10 at 05:20

13 Answers13

131

Here is how I remember when to use what -

Semaphore: Use a semaphore when you (thread) want to sleep till some other thread tells you to wake up. Semaphore 'down' happens in one thread (producer) and semaphore 'up' (for same semaphore) happens in another thread (consumer) e.g.: In producer-consumer problem, producer wants to sleep till at least one buffer slot is empty - only the consumer thread can tell when a buffer slot is empty.

Mutex: Use a mutex when you (thread) want to execute code that should not be executed by any other thread at the same time. Mutex 'down' happens in one thread and mutex 'up' must happen in the same thread later on. e.g.: If you are deleting a node from a global linked list, you do not want another thread to muck around with pointers while you are deleting the node. When you acquire a mutex and are busy deleting a node, if another thread tries to acquire the same mutex, it will be put to sleep till you release the mutex.

Spinlock: Use a spinlock when you really want to use a mutex but your thread is not allowed to sleep. e.g.: An interrupt handler within OS kernel must never sleep. If it does the system will freeze / crash. If you need to insert a node to globally shared linked list from the interrupt handler, acquire a spinlock - insert node - release spinlock.

j0k
  • 22,600
  • 28
  • 79
  • 90
Annu Gogatya
  • 1,339
  • 1
  • 8
  • 3
  • 4
    to add to: semaphores and the mutex are two ways to provide synchronisation. semaphore, can be more related to signalling (e.g. producer and consumer problem scenario), and mutex, can be more related to allowing access to one at a time (several requests to access shared resource, but only one granted at a time). [nice article: http://www.geeksforgeeks.org/mutex-vs-semaphore/] – parasrish Apr 24 '17 at 04:22
  • 1
    Just one *possible* nitpick, mutexes really protect *resources,* not code. Access to those resources may be performed in widely dispersed code sections so, as long as *all* those sections use the same mutex, everything should be fine. The way your answer reads (to me) is that the mutex protects only *one* section of code. – paxdiablo Sep 25 '21 at 04:23
  • For the last one I would say, Spinlock: Kernel developer? No? Then no. – Hunter Kohler Sep 26 '22 at 23:31
62

A mutex is a mutual exclusion object, similar to a semaphore but that only allows one locker at a time and whose ownership restrictions may be more stringent than a semaphore.

It can be thought of as 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).

A semaphore, on the other hand, has an arbitrary 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 (P and V) used for claiming and releasing semaphores, it's because the inventor was Dutch. In that language:

  • Probeer te verlagen: means to try to lower;
  • Verhogen: means to increase.

(a) ... or it can be thought of as something totally distinct from a semaphore, which may be safer given their almost-always-different uses.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • Okay, I came across binary semaphore too. When should we need to go in for binary semaphore and when should we use mutex ? – Karthik Balaguru Oct 28 '10 at 05:08
  • 1
    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 Oct 28 '10 at 05:12
  • 1
    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 Oct 28 '10 at 05:21
  • Recursive mutex are evil, they show that the ressource handling is not properly mastered. – Patrick Schlüter Oct 28 '10 at 06:08
  • 1
    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 Oct 28 '10 at 07:05
  • 6
    A mutex is totally different from a binary semaphore. Sorry but this definition is wrong – Peer Stritzinger Oct 28 '10 at 14:37
  • @PeerStritzinger Agreed, your answer captures the ownership differences between them and the reason why mutexs are not used in synchronsing tasks while semaphores are. Thanks for the article and the answer. – legends2k Oct 01 '13 at 11:30
  • @legends2k, that was probably best as a comment on Peer's answer rather than mine. In any case, the ownership issue and other differences are covered in this answer, maybe not as detailed as Peer's but certainly there. You should also vote up Peer's answer if you haven't already done so. – paxdiablo Oct 01 '13 at 12:32
  • @paxdiablo: Yes, but I felt it a bit ambigious; the comment "binary semaphore _is_ mutex" makes it more so. Yes, I did upvote his answer. – legends2k Oct 01 '13 at 13:14
  • @paxdiablo - While this answer could be considered technically correct - indeed is similar to descriptions seen many other places - I agree with PeerStritzinger that it is not good to equate a mutex to a binary semaphor. Doing so leads to muddled thinking - demonstrated by your comment "a resource should only be releasable by the thread that claimed it". Semaphores exist *so that* responsibility can be handed off to someone else - like a baton in a baton race, or token passing. They wouldn't be useful if the original thread had to be involved in freeing the resource! – ToolmakerSteve Feb 02 '17 at 05:46
  • ... A `mutex` is a statement "hands off until I am done"; for a resource that already is known to exist. And that will continue to exist after the mutex is released. A `binary semaphore` is appropriate when the resource does not exist until a `producer` provides it. After a `consumer` comes along and acquires that resource *it is gone forever* (unless/until a `producer` produces another one). These are different concepts. Yes, it is possible to mis-use mutex or semaphor for the other purpose. But that would be a mistake. – ToolmakerSteve Feb 02 '17 at 06:01
  • Hmm. Even the Wikipedia Semaphore article discusses using a counting semaphore to control a pool of resources. But doing so has severe risks, see [Part 1 Semaphores](https://blog.feabhas.com/2009/09/mutex-vs-semaphores-%E2%80%93-part-1-semaphores/). Unfortunately, I am not expert enough to resolve the discrepancy between practice and theory. – ToolmakerSteve Feb 02 '17 at 06:17
  • 1
    @ToolmakerSteve, I'm not sure if you understood my intent there. I stated a *mutex* was like a semaphore with count one and the restriction that the claiming thread be the releasing one. I did not contend that a *semaphore* had that restriction. I'll try clean up the answer to better distinguish. – paxdiablo Feb 02 '17 at 06:21
  • @paxdiablo As you say that it can be thought of as 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 question arises***, does the implementation of mutex and semaphore have any relation (for standard library)? – John Sep 23 '21 at 01:56
  • @paxdiablo "Dutch. Probeer te verlagen means to try and decrease while verhogen means to increase."? Any clerical error? What's that? – John Sep 23 '21 at 02:50
  • @John, `P` and `V` are the normal operations on a counting semaphore, I was just explaining where they came from. In terms of whether implementations are similar, it's possible. But, given how insanely efficient you'd want them to be and the fact that mutex operations are a lot simpler to implement, a mutex would likely not be done in terms of a semaphore. However, you could quite easily construct a counting semaphore using a mutex to control access to the count, but it probably depends on whether there's a better way in whatever architecture you're targeting. – paxdiablo Sep 25 '21 at 04:06
58

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 (Accidental 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 has to be released by the same task it is not very good for the 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 between 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

Mohammad Kholghi
  • 533
  • 2
  • 7
  • 21
Peer Stritzinger
  • 8,232
  • 2
  • 30
  • 43
  • The urls to this site contain funky characters and do not work therefore... I'm working on it – Peer Stritzinger Oct 28 '10 at 14:15
  • 1
    The links are dead. The answer does not explain what is the difference between the **specifications** of binary semaphore and mutex. “The principle of ownership” is about how a synchronization primitive is used, hence it does not belong to a specification. Downvoting. – beroal Mar 11 '21 at 19:40
  • 2
    @beroal I have edited this, and the links are updated. Wait till the update is accepted and enjoy reading them... – Mohammad Kholghi Sep 15 '21 at 07:08
  • For part 3, I don't understand why circular dead lock can't occure with mutex. If SI task execute "mutex_lock(DAC)" and after RTOS switch to Control task, circular dead lock appears, isn't it ? – ipStack Jul 08 '22 at 08:03
  • @beroal The ownership aspect of a mutex is not just a usage issue. Only the task that takes a mutex can release it. For recursive mutexes, if one task takes a semaphore and then calls a routine that takes the same semaphore, it gets it, because the task has taken it. If another task calls that same routine that takes the same semaphore, it will fail because the first task still owns it. – Jeff Learman Nov 29 '22 at 18:43
15

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_unlock(mutex_thing); // unlock mutex

The semaphore 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

B_San
  • 108
  • 12
Patrick Schlüter
  • 11,394
  • 1
  • 43
  • 48
  • 4
    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 Oct 28 '10 at 06:40
  • 1
    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 Oct 28 '10 at 07:07
  • `You say that the usage pattern of semaphores is to notify threads` One point about notifying threads. You can call `sem_post` from a signal handler safely (http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html) but it is not recomended to call `pthread_mutex_lock` and `pthread_mutex_unlock` from signal handlers (http://manpages.ubuntu.com/manpages/lucid/man3/pthread_mutex_init.3.html#contenttoc4) –  Mar 05 '13 at 12:13
  • @paxdiablo: There is one major difference between this mutex binary semaphore is maintaining the reference count. Mutex or you can say any conditional mutex does not maintain any count related to lock where as sempahore use to maintain the count. So sem_wait and sem_post are maintaining the count. – Prak Jul 14 '13 at 12:56
  • Highlight on "The mutex is used for protecting parts of code from running concurrently, semaphores are used for one thread to signal another thread to run" – John Sep 23 '21 at 03:08
14

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
  • 2,877
  • 3
  • 25
  • 38
  • Note that there is another difference. First, you can have a binarly semaphore (equivalent to a counting semaphore with max count of 1.) So, the number of keys is not the only difference. Second only the person who got a mutex can return it. With semaphores, anyone can return the key, even someone who doesn't "have" it. Furthermore, mutexes are often "recursive," so if a task takes a semaphore and calls a function that takes the same semaphore, it succeeds, because that task has the mutex. If another task meanwhile calls that same function, it waits, because another task has the mutex. – Jeff Learman Nov 29 '22 at 18:50
7

Mutex is to protect the shared resource.
Semaphore is to dispatch the threads.

Mutex:
Imagine that there are some tickets to sell. We can simulate a case where many people buy the tickets at the same time: each person is a thread to buy tickets. Obviously we need to use the mutex to protect the tickets because it is the shared resource.


Semaphore:
Imagine that we need to do a calculation as below:

c = a + b;

Also, we need a function geta() to calculate a, a function getb() to calculate b and a function getc() to do the calculation c = a + b.

Obviously, we can't do the c = a + b unless geta() and getb() have been finished.
If the three functions are three threads, we need to dispatch the three threads.

int a, b, c;
void geta()
{
    a = calculatea();
    semaphore_increase();
}

void getb()
{
    b = calculateb();
    semaphore_increase();
}

void getc()
{
    semaphore_decrease();
    semaphore_decrease();
    c = a + b;
}

t1 = thread_create(geta);
t2 = thread_create(getb);
t3 = thread_create(getc);
thread_join(t3);

With the help of the semaphore, the code above can make sure that t3 won't do its job untill t1 and t2 have done their jobs.

In a word, semaphore is to make threads execute as a logicial order whereas mutex is to protect shared resource.
So they are NOT the same thing even if some people always say that mutex is a special semaphore with the initial value 1. You can say like this too but please notice that they are used in different cases. Don't replace one by the other even if you can do that.

Yves
  • 11,597
  • 17
  • 83
  • 180
  • Selling tickets is a neat example. semaphore example is bit unclear (to me anyway). – prayagupa Aug 16 '17 at 00:40
  • 1
    @prayagupd Semaphore example is to make threads in some order whereas selling tickets doesn't need any order. If there are three people: a, b and c. When they come to buy tickets, we don't care the order of buying tickets at all. However, if we do such a calculation: `x = getx(); y = gety(); z = x + y;` For some reason, we use three threads to do the three things, now the order of threads is very important because we can't do `x + y` unless `getx` and `gety` have finished. In a word, semaphore is used when we care about the order of execution of multi-threading. – Yves Aug 16 '17 at 01:19
  • got you. It sounds similar to [barrier](https://en.wikipedia.org/wiki/Barrier_(computer_science)). I can say that wait until threads `x` and `y` are completed, then calculate `z = x + y`. I know java has [`CyclicBarrier`](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CyclicBarrier.html). Also, I'm not sure if I can say `mapreduce` is semaphore usecase too, because I can not `reduce` until all `map`s are completed. – prayagupa Aug 16 '17 at 01:33
  • @prayagupd Yes. You can say that. – Yves Aug 16 '17 at 02:12
6

Trying not to sound zany, but can't help myself.

Your question should be what is the difference between mutex and semaphores ? And to be more precise question should be, 'what is the relationship between mutex and semaphores ?'

(I would have added that question but I'm hundred % sure some overzealous moderator would close it as duplicate without understanding difference between difference and relationship.)

In object terminology we can observe that :

observation.1 Semaphore contains mutex

observation.2 Mutex is not semaphore and semaphore is not mutex.

There are some semaphores that will act as if they are mutex, called binary semaphores, but they are freaking NOT mutex.

There is a special ingredient called Signalling (posix uses condition_variable for that name), required to make a Semaphore out of mutex. Think of it as a notification-source. If two or more threads are subscribed to same notification-source, then it is possible to send them message to either ONE or to ALL, to wakeup.

There could be one or more counters associated with semaphores, which are guarded by mutex. The simple most scenario for semaphore, there is a single counter which can be either 0 or 1.

This is where confusion pours in like monsoon rain.

A semaphore with a counter that can be 0 or 1 is NOT mutex.

Mutex has two states (0,1) and one ownership(task). Semaphore has a mutex, some counters and a condition variable.

Now, use your imagination, and every combination of usage of counter and when to signal can make one kind-of-Semaphore.

  1. Single counter with value 0 or 1 and signaling when value goes to 1 AND then unlocks one of the guy waiting on the signal == Binary semaphore

  2. Single counter with value 0 to N and signaling when value goes to less than N, and locks/waits when values is N == Counting semaphore

  3. Single counter with value 0 to N and signaling when value goes to N, and locks/waits when values is less than N == Barrier semaphore (well if they dont call it, then they should.)

Now to your question, when to use what. (OR rather correct question version.3 when to use mutex and when to use binary-semaphore, since there is no comparison to non-binary-semaphore.) Use mutex when 1. you want a customized behavior, that is not provided by binary semaphore, such are spin-lock or fast-lock or recursive-locks. You can usually customize mutexes with attributes, but customizing semaphore is nothing but writing new semaphore. 2. you want lightweight OR faster primitive

Use semaphores, when what you want is exactly provided by it.

If you dont understand what is being provided by your implementation of binary-semaphore, then IMHO, use mutex.

And lastly read a book rather than relying just on SO.

Ajeet Ganga
  • 8,353
  • 10
  • 56
  • 79
5

I think the question should be the difference between mutex and binary semaphore.

Mutex = It is a ownership lock mechanism, only the thread who acquire the lock can release the lock.

binary Semaphore = It is more of a signal mechanism, any other higher priority thread if want can signal and take the lock.

Saurabh Sengar
  • 878
  • 2
  • 12
  • 20
2

All the above answers are of good quality,but this one's just to memorize.The name Mutex is derived from Mutually Exclusive hence you are motivated to think of a mutex lock as Mutual Exclusion between two as in only one at a time,and if I possessed it you can have it only after I release it.On the other hand such case doesn't exist for Semaphore is just like a traffic signal(which the word Semaphore also means).

1

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
  • 54,333
  • 19
  • 131
  • 194
1

A mutex is a special case of a semaphore. A semaphore allows several threads to go into the critical section. When creating a semaphore you define how may threads are allowed in the critical section. Of course your code must be able to handle several accesses to this critical section.

Frode Akselsen
  • 616
  • 2
  • 8
  • 23
0

I find the answer of @Peer Stritzinger the correct one.

I wanted to add to his answer the following quote from the book Programming with POSIX Threads by David R Butenhof. On page 52 of chapter 3 the author writes (emphasis mine):

You cannot lock a mutex when the calling thread already has that mutex locked. The result of attempting to do so may be an error return (EDEADLK), or it may be a self-deadlock, where the unfortunate thread waits forever. You cannot unlock a mutex that is unlocked, or that is locked by another thread. Locked mutexes are owned by the thread that locks them. If you need an "unowned" lock, use a semaphore. Section 6.6.6 discusses semaphores)

With this in mind, the following piece of code illustrates the danger of using a semaphore of size 1 as a replacement for a mutex.

sem = Semaphore(1)
counter = 0 // shared variable
----

Thread 1

for (i in 1..100):
  sem.lock()
  ++counter
  sem.unlock()
----

Thread 2

for (i in 1..100):
  sem.lock()
  ++counter
  sem.unlock()
----

Thread 3

sem.unlock()
thread.sleep(1.sec)
sem.lock()

If only for threads 1 and 2, the final value of counter should be 200. However, if by mistake that semaphore reference was leaked to another thread and called unlock, than you wouldn't get mutual exclusion. With a mutex, this behaviour would be impossible by definition.

cmhteixeira
  • 877
  • 11
  • 22
-1

Binary semaphore and Mutex are different. From OS perspective, a binary semaphore and counting semaphore are implemented in the same way and a binary semaphore can have a value 0 or 1.

Mutex -> Can only be used for one and only purpose of mutual exclusion for a critical section of code.

Semaphore -> Can be used to solve variety of problems. A binary semaphore can be used for signalling and also solve mutual exclusion problem. When initialized to 0, it solves signalling problem and when initialized to 1, it solves mutual exclusion problem.

When the number of resources are more and needs to be synchronized, we can use counting semaphore.

In my blog, I have discussed these topics in detail.

https://designpatterns-oo-cplusplus.blogspot.com/2015/07/synchronization-primitives-mutex-and.html

Rags
  • 19
  • 1
  • 5