When Should We Use Mutex and When Should We Use Semaphore

In what situation do you use a semaphore over a mutex in C++?

Boost.Thread has mutexes and condition variables. Purely in terms of functionality, semaphores are therefore redundant[*], although I don't know if that's why they're omitted.

Semaphores are a more basic primitive, simpler, and possibly implemented to be faster, but don't have priority-inversion avoidance. They're arguably harder to use than condition variables, because they require the client code to ensure that the number of posts "matches" the number of waits in some appropriate way. With condition variables it's easy to tolerate spurious posts, because nobody actually does anything without checking the condition.

Read vs. write resources is a red herring IMO, it has nothing to do with the difference between a mutex and a semaphore. If you use a counting semaphore, you could have a situation where multiple threads are concurrently accessing the same resource, in which case it would presumably have to be read-only access. In that situation, you might be able to use shared_mutex from Boost.Thread instead. But semaphores aren't "for" protecting resources in the way mutexes are, they're "for" sending a signal from one thread to another. It's possible to use them to control access to a resource.

That doesn't mean that all uses of semaphores must relate to read-only resources. For example, you can use a binary semaphore to protect a read/write resource. Might not be a good idea, though, since a mutex often gives you better scheduling behaviour.

[*] Here's roughly how you implement a counting semaphore using a mutex and a condition variable. To implement a shared semaphore of course you need a shared mutex/condvar:

struct sem {
mutex m;
condvar cv;
unsigned int count;
};

sem_init(s, value)
mutex_init(s.m);
condvar_init(s.cv);
count = value;

sem_wait(s)
mutex_lock(s.m);
while (s.count <= 0) {
condvar_wait(s.cv, s.m);
}
--s.count;
mutex_unlock(s.m);

sem_post(s)
mutex_lock(s.m);
++s.count;
condvar_broadcast(s.cv)
mutex_unlock(s.m);

Therefore, anything you can do with semaphores, you can do with mutexes and condition variables. Not necessarily by actually implementing a semaphore, though.

What is the difference between semaphore and mutex in implementation?

Assuming you know the basic differences between a sempahore and mutex :

For fast, simple synchronization, use a critical section.

To synchronize threads across process boundaries, use mutexes.

To synchronize access to limited resources, use a semaphore.

Apart from the fact that mutexes have an owner, the two objects may be optimized for different usage. Mutexes are designed to be held only for a short time; violating this can cause poor performance and unfair scheduling. For example, a running thread may be permitted to acquire a mutex, even though another thread is already blocked on it, creating a deadlock. Semaphores may provide more fairness, or fairness can be forced using several condition variables.

What is the difference between lock, mutex and semaphore?

A lock allows only one thread to enter the part that's locked and the lock is not shared with any other processes.

A mutex is the same as a lock but it can be system wide (shared by multiple processes).

A semaphore does the same as a mutex but allows x number of threads to enter, this can be used for example to limit the number of cpu, io or ram intensive tasks running at the same time.

For a more detailed post about the differences between mutex and semaphore read here.

You also have read/write locks that allows either unlimited number of readers or 1 writer at any given time.

Producer Consumer should I use a mutex or a semaphore

Either can be made to work. It depends on details of the actual design. How many producer/consumer requests will you allow simultaneously? Is it truly limited to two threads, or will the code spawn others as more requests occur?

I found this short blog interesting. It discusses and compares both the Mutex and Semaphore and may give you some ideas.

"A mutex object allows multiple process threads to access a single shared resource but only one at a time. On the other hand, semaphore
allows multiple process threads to access the finite instance of the
resource until available. In mutex, the lock can be acquired and
released by the same process at a time."

Examples in C

  • One queue accessed by multiple threads using mutex

  • Blocking Queue in C++ using semaphores (Not C specific, but concept will be same.)



Related Topics



Leave a reply



Submit