What is the Re-entrant lock and concept in general? - multithreading

I always get confused. Would someone explain what Reentrant means in different contexts? And why would you want to use reentrant vs. non-reentrant?
Say pthread (posix) locking primitives, are they re-entrant or not? What pitfalls should be avoided when using them?
Is mutex re-entrant?

Re-entrant locking
A reentrant lock is one where a process can claim the lock multiple times without blocking on itself. It's useful in situations where it's not easy to keep track of whether you've already grabbed a lock. If a lock is non re-entrant you could grab the lock, then block when you go to grab it again, effectively deadlocking your own process.
Reentrancy in general is a property of code where it has no central mutable state that could be corrupted if the code was called while it is executing. Such a call could be made by another thread, or it could be made recursively by an execution path originating from within the code itself.
If the code relies on shared state that could be updated in the middle of its execution it is not re-entrant, at least not if that update could break it.
A use case for re-entrant locking
A (somewhat generic and contrived) example of an application for a re-entrant lock might be:
You have some computation involving an algorithm that traverses a graph (perhaps with cycles in it). A traversal may visit the same node more than once due to the cycles or due to multiple paths to the same node.
The data structure is subject to concurrent access and could be updated for some reason, perhaps by another thread. You need to be able to lock individual nodes to deal with potential data corruption due to race conditions. For some reason (perhaps performance) you don't want to globally lock the whole data structure.
Your computation can't retain complete information on what nodes you've visited, or you're using a data structure that doesn't allow 'have I been here before' questions to be answered quickly. An example of this situation would be a simple implementation of Dijkstra's algorithm with a priority queue implemented as a binary heap or a breadth-first search using a simple linked list as a queue. In these cases, scanning the queue for existing insertions is O(N) and you may not want to do it on every iteration.
In this situation, keeping track of what locks you've already acquired is expensive. Assuming you want to do the locking at the node level a re-entrant locking mechanism alleviates the need to tell whether you've visited a node before. You can just blindly lock the node, perhaps unlocking it after you pop it off the queue.
Re-entrant mutexes
A simple mutex is not re-entrant as only one thread can be in the critical section at a given time. If you grab the mutex and then try to grab it again a simple mutex doesn't have enough information to tell who was holding it previously. To do this recursively you need a mechanism where each thread had a token so you could tell who had grabbed the mutex. This makes the mutex mechanism somewhat more expensive so you may not want to do it in all situations.
IIRC the POSIX threads API does offer the option of re-entrant and non re-entrant mutexes.

A re-entrant lock lets you write a method M that puts a lock on resource A and then call M recursively or from code that already holds a lock on A.
With a non re-entrant lock, you would need 2 versions of M, one that locks and one that doesn't, and additional logic to call the right one.

Reentrant lock is very well described in this tutorial.
The example in the tutorial is far less contrived than in the answer about traversing a graph. A reentrant lock is useful in very simple cases.

The what and why of recursive mutex should not be such a complicated thing described in the accepted answer.
I would like to write down my understanding after some digging around the net.
First, you should realize that when talking about mutex, multi thread concepts is definitely involved too. (mutex is used for synchronization. I don't need mutex if I only have 1 thread in my program)
Secondly, you should know the difference bewteen a normal mutex and a recursive mutex.
Quoted from APUE:
(A recursive mutex is a) A mutex type that allows the same thread to lock
it multiple times without first unlocking it.
The key difference is that within the same thread, relock a recursive lock does not lead to deadlock, neither block the thread.
Does this mean that recusive lock never causes deadlock?
No, it can still cause deadlock as normal mutex if you have locked it in one thread without unlocking it, and try to lock it in other threads.
Let's see some code as proof.
normal mutex with deadlock
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t lock;
void * func1(void *arg){
printf("thread1\n");
pthread_mutex_lock(&lock);
printf("thread1 hey hey\n");
}
void * func2(void *arg){
printf("thread2\n");
pthread_mutex_lock(&lock);
printf("thread2 hey hey\n");
}
int main(){
pthread_mutexattr_t lock_attr;
int error;
// error = pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_RECURSIVE);
error = pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_DEFAULT);
if(error){
perror(NULL);
}
pthread_mutex_init(&lock, &lock_attr);
pthread_t t1, t2;
pthread_create(&t1, NULL, func1, NULL);
pthread_create(&t2, NULL, func2, NULL);
pthread_join(t2, NULL);
}
output:
thread1
thread1 hey hey
thread2
common deadlock example, no problem.
recursive mutex with deadlock
Just uncomment this line
error = pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_RECURSIVE);
and comment out the other one.
output:
thread1
thread1 hey hey
thread2
Yes, recursive mutex can also cause deadlock.
normal mutex, relock in the same thread
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
pthread_mutex_t lock;
void func3(){
printf("func3\n");
pthread_mutex_lock(&lock);
printf("func3 hey hey\n");
}
void * func1(void *arg){
printf("thread1\n");
pthread_mutex_lock(&lock);
func3();
printf("thread1 hey hey\n");
}
void * func2(void *arg){
printf("thread2\n");
pthread_mutex_lock(&lock);
printf("thread2 hey hey\n");
}
int main(){
pthread_mutexattr_t lock_attr;
int error;
// error = pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_RECURSIVE);
error = pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_DEFAULT);
if(error){
perror(NULL);
}
pthread_mutex_init(&lock, &lock_attr);
pthread_t t1, t2;
pthread_create(&t1, NULL, func1, NULL);
sleep(2);
pthread_create(&t2, NULL, func2, NULL);
pthread_join(t2, NULL);
}
output:
thread1
func3
thread2
Deadlock in thread t1, in func3.
(I use sleep(2) to make it easier to see that the deadlock is firstly caused by relocking in func3)
recursive mutex, relock in the same thread
Again, uncomment the recursive mutex line and comment out the other line.
output:
thread1
func3
func3 hey hey
thread1 hey hey
thread2
Deadlock in thread t2, in func2. See? func3 finishes and exits, relocking does not block the thread or lead to deadlock.
So, last question, why do we need it ?
For recursive function (called in multi-threaded programs and you want to protect some resource/data).
E.g. You have a multi thread program, and call a recursive function in thread A. You have some data that you want to protect in that recursive function, so you use the mutex mechanism. The execution of that function is sequential in thread A, so you would definitely relock the mutex in recursion. Use normal mutex causes deadlocks. And resursive mutex is invented to solve this.
See an example from the accepted answer
When to use recursive mutex?.
The Wikipedia explains the recursive mutex very well. Definitely worth for a read. Wikipedia: Reentrant_mutex

Related

Must lock be held when signaling conditional variable?

OK. The example here is provided using pthread lib in c.
In textbook I came across the following code:
//for thread 2
pthread_mutex_lock(&lock);
should_wake_up = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);
This code works out pretty fine. I just wonder will the following code also works?
//for thread 2
pthread_mutex_lock(&lock);
should_wake_up = 1;
pthread_mutex_unlock(&lock);
pthread_cond_signal(&cond);//signal the conditional variable but the lock is not held
What's the pros and cons for the following code?
PS. Suppose the cooperating thread has the code:
//for thread 1
pthread_mutex_lock(&lock);
while(!should_wake_up)
pthread_cond_wait(&cond, &lock);
pthead_mutex_unlock(&lock);
PS2. I came across some other question, which points out that if we don't want signal being lost, we must use lock to make sure that the associated predicate (in this case, is should_wake_up) can not be changed when the lock is held in thread 1. In this case, this seems not to be the issue. Link to the post: [1]: signal on condition variable without holding lock. I think his issue is that he forget about locking. But my question is different.
For normal usage, you can unlock the mutex before signalling a condition variable.
The mutex protects the shared state (in this case the should_wake_up flag). Provided the mutex is locked when modifying the shared state, and when checking the shared state, pthread_cond_signal can be called without the mutex locked and everything will work as expected.
Under most circumstances, I would recommend calling pthread_cond_signal after calling pthread_mutex_unlock as a slight performance improvement. If you call pthread_cond_signal before pthread_mutex_unlock then the waiting thread can be woken by the signal before the mutex is unlocked, so the waiting thread then has to go back to sleep, as it blocks on the mutex that is still held by the signalling thread.

What is a Spinning Thread?

I have stumbled upon the term spinning, referring to a thread while reading this (ROS)
What is the general concept behind spinning a thread?
My intuition would say that a spinning thread is a thread that keeps executing in a multithreading process with a certain frequency, somewhat related to the concept of polling (i.e. keep checking some condition with a certain frequency) but I am not sure at all about it.
Could you give some explanation? The more general the better.
There are a couple of separate concepts here.
In terms of ROS (the link you reference), ros::spin() runs the ROS callback invoker, so that pending events are delivered to your program callbacks via a thread belonging to your program. This sort of call typically does not return; it will wait for new events to be ready, and invoke appropriate callbacks when they occur.
But you also refer to "spinning a thread."
This is a separate topic. It generally relates to a low level programming pattern whereby a thread will repeatedly check for some condition being met without being suspended.
A common way to wait for some condition to be met is to just wait on a conditional variable. In this example, the thread will be suspended by the kernel until some other thread calls notify on the condition variable. Upon the notify, the kernel will resume the thread, and the condition will evaluate to true, allowing the thread to continue.
std::mutex m;
std::condition_variable cv;
bool ready = false;
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{ return ready; }); /* thread suspended */
Alternatively a spinning approach would repeatedly check some condition, without going to sleep. Caution: this results in high CPU, and there are subtle caveats to implementing correctly).
Here is an example of a simple spinlock (although note that spinning threads can be used for other purposes than spinlocks). In the below code, notice that the while loop repeatedly calls test_and_set ... which is just an attempt to set the flag to true; that's the spin part.
// spin until true
std::atomic_flag lock = ATOMIC_FLAG_INIT;
while (lock.test_and_set(std::memory_order_acquire)); // acquire lock
/* got the flag .. do work */
lock.clear(std::memory_order_release); // release lock
spin like while loop without sleeping, your task consumes cpu resource constantly until the conditions is satisfied.

Does C++11 locks make a call to the kernel [duplicate]

I have the following situation:
Two C++11 threads are working on a calculation and they are synchronized through a std::mutex.
Thread A locks the mutex until the data is ready for the operation Thread B executes. When the mutex is unlocked Thread B starts to work.
Thread B tries to lock the mutex and is blocked until it is unlocked by Thread A.
void ThreadA (std::mutex* mtx, char* data)
{
mtx->lock();
//do something useful with data
mtx->unlock();
}
void ThreadB (std::mutex* mtx, char* data)
{
mtx->lock(); //wait until Thread A is ready
//do something useful with data
//.....
}
It is asserted that Thread A can block the mutex first.
Now I am wondering if the mtx->lock() in Thread B waits active or passive. So is Thread B polling the mutex state and wasting processor time or is released passively by the sheduler when the mutex is unlocked.
In the different C++ references it is only mentioned that the thread is blocked, but not in which way.
Could it be, however, that the std::mutex implementation is hardly depended on the used plattform and OS?
It's highly implementation defined, even for the same compiler and OS
for example,on VC++, in Visual Studio 2010, std::mutex was implemented with Win32 CRITICAL_SECTION. EnterCriticalSection(CRITICAL_SECTION*) has some nice feature: first it tries to lock the CRITICAL_SECTION by iterating on the lock again and again. after specified number of iteration, it makes a kernel-call which makes the thread go sleep, only to be awakened up again when the lock is released and the whole deal starts again.
in this case , the mechanism polls the lock again and again before going to sleep, then the control switches to the kernel.
Visual Studio 2012 came with a different implementation. std::mutex was implemented with Win32 mutex. Win32 mutex shifts the control immediately to the kernel. there is no active polling done by the lock.
you can read about the implementation switch in the answer : std::mutex performance compared to win32 CRITICAL_SECTION
So, it is unspecified how the mutex acquires the lock. it is the best not to rely on such behaviour.
ps. do not lock the mutex manually, use std::lock_guard instead. also, you might want to use condition_variable for more-refined way of controlling your synchronization.

Binary Semaphore as resource access controller: Multithreading POSIX

As per multithreading concepts, I have learned so far:
MUTEX: A mutex_t object can be used for managing access to a resource.
BINARY SEMAPHORE: A sem_t object can also be used to manage access to a resource
Differenrce between two: The concept of ownership i.e. in case of mutex_t the thread which locked the mutex_t, only it can unlock it. But in case of sem_t, there is no concpt of ownership and hence any thread can perform sem_post() on the sem_t object. This is the reson it can be used as Event signals.
Now suppose my crital section appears as:
A) Using mutex_t
typedef struct {
int count;
pthread_mutex_t mutex;
}counter;
counter count;
void increment(counter* c)
{
pthread_mutex_lock(&(c->mutex));
(c->count)++;
pthread_mutex_unlock(&(c->mutex));
}
B) Using sem_t
EDIT: (Binary semaphore i.e. initialized to 1)
typedef struct {
int count;
sem_t sem;
}counter;
counter count;
void increment(counter* c)
{
sem_wait(&(c->sem));
(c->count)++;
sem_post(&(c->sem));
}
In case of B) till the time sem is zero no thread can enter the critical section and hence providing access control. But suppose due to some event sem_post() is executed by some other thread then it will allow access to critical section by other threads.
In this case this is actually a buggy situation and not a proper a access control.And hence programmer has to be careful with use of binary semaphore for resource access control.
I can conclude, it always better to use mutex_t for access control and binary semaphore for event signalling.
Please let me know if my understanding is correct or am I missing something?
Mutexes are very specific in their purpose. Like you said, they can only ever be released by the thread currently holding the mutex, and they only allow single entrancy. A mutex is effectively a semaphore initialized to a count of 1 that also verifies that the thread calling post is the thread that last called wait ('ownership' invariance).
Your example does not show the initalization conditions for your semaphore. If you wanted to use it in the same way as a mutex, it would have to be initialized to a count of 1.
Semaphores do have a wide range of uses, so I wouldn't call them 'unsafe'. For example, lets say that you have some resource that allows, say, 5 total consumers to be running. So you would protect that resource with a semaphore initialized to 5. As consumers invoke the resource, the semaphore will tick down until it hits zero, at which point it'll block new consumers until running consumers increment the semaphore. This is called a counting semaphore.
A great example of how to use a counting semaphore is a blocking queue - a simple Queue that has an Enqueue and a Dequeue method. Each Enqueue increments the semaphore, and each Dequeue decrements the semaphore. In this way, if the queue is empty, Dequeuers will be blocked.
Another example of how a semaphore could be used would be in a simple signaling situation, as you mention:
Thread A enqueues 10 jobs into a thread pool to run them in parallel. Each job has a semaphore associated with it that is initially set to 0. When the job has been completed by the thread pool, the thread pool posts to the jobs semaphore. Meanwhile, Thread A is waiting on each job's semaphore to find out when they complete.
So we see many uses for a semaphore:
Making Mutexs, where the initial count = 1
Protecting limited resources, where the initial count = N, the limit
Counting queued work, where the initial count is = 0 and grows with queued work
Signaling job completion, where the initial count = 0, and the semaphore is used to coordinate two threads.
I would remind you that locking in general is a topic that requires close attention - in systems that have complex interactions, its sometimes very easy to use too little locking, causing unintended concurrency, or too much locking, causing deadlocks.

When should we use mutex and when should we use semaphore

When should we use mutex and when should we use semaphore ?
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.
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.
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
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
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
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.
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.
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
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
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.
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.
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).
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.
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.
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.
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

Resources