Granting priority access to a std::mutex - multithreading

I currently have two functions like this that share the same mutex.
void fooA()
{
{
std::lock_guard<std::mutex> guard(myMutex);
doWork()
}
}
void fooB()
{
{
std::lock_guard<std::mutex> guard(myMutex);
doWork()
}
}
My question is if it is possible to specify that fooA() mutex should be given priority/preference ?
I understand that mutexes is first come first serve. Say there are four threads t1,t2,t3,t4. Now suppose thread t1 currently owns the mutex in fooB() and t2 and t3 are waiting in line for the mutex in fooB() whereas thread t4 is waiting in line for the mutex at fooA(). What I would like is for thread t4 to be given priority next since its accessing fooA() and lets t2,t3 continue waiting. All of this should be done after t1 releases the mutex

Considering that your problem is not in the MUTEX lock of functions running inside your process but of priority queuing within your multi-threaded environment, as long as you have access to the thread creation functions-- to set the priority of each called thread, you can use:
#include <sched.h>
int sched_setscheduler(pid_t pid, int policy,
const struct sched_param *param);
int sched_getscheduler(pid_t pid);
struct sched_param {
...
int sched_priority;
...
};
Some issues you may run into are (1) if the newly minted priority thread is then commandeering the mutex without giving the lower priority threads a chance. (2) If you set multiple threads to equally high priority (can be overridden by correcting this or setting a Round Robin Scheduling Scheme) (3) Priority Inversion is still possible.
This is my first SO answer so hope it helps! If you want more info check out the references, especially (2) which gives primitive answers to this problem!
References:
(1) https://linux.die.net/man/2/sched_setscheduler
(2) How to give priority to privileged thread in mutex locking?
(3) https://www.ibm.com/docs/en/aix/7.2?topic=programming-synchronization-scheduling

Related

deadlock using condition variable

I have a question about condition_variable.
Having this code
#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>
std::condition_variable cv;
std::mutex mut;
int value;
void sleep() {
std::unique_lock<std::mutex> lock(mut);
// sleep forever
cv.notify_one();
}
int main ()
{
std::thread th (sleep);
std::unique_lock<std::mutex> lck(mut);
if(cv.wait_for(lck,std::chrono::seconds(1))==std::cv_status::timeout) {
std::cout << "failed" << std::endl;
}
th.join();
return 0;
}
How to resolve this deadlock
Why the wait_for blocks even after the 1 sec.
Is the mut necessary for the thread th ?
Thanks.
Why the wait_for blocks even after the 1 sec?
How do you know that the main thread ever makes it to the cv.wait_for(...) call?
It's not 100% clear what you are asking, but if the program never prints "failed," and you are asking why not, then probably what happened is, the child thread locked the mutex first and then it "slept forever" while keeping the mutex locked. If that happened, then the main thread would never be able to get past the std::unique_lock<std::mutex> lck(mut); line.
Is the mut necessary for the thread th ?
That depends. You certainly don't need to lock a mutex in a thread that does nothing but "// sleep forever," but maybe the thread that you are asking about is not exactly the same as what you showed. Maybe you are asking how wait() and notify() are supposed to be used.
I can't give a C++-specific answer, but in most programming languages and libraries, wait() and notify() are low-level primitives that are meant to be used in a very specific way:
A "consumer" thread waits by doing something like this:
mutex.lock();
while ( ! SomeImportantCondition() ) {
cond_var.wait(mutex);
}
DoSomethingThatRequiresTheConditionToBeTrue();
mutex.unlock()
The purpose of the mutex is to protect the shared data that SomeImportantCondition() tests. No other thread should be allowed to change the value that SomeImportantCondition() returns while the mutex is locked.
Also, you may already know this, but some readers might not; The reason why mutex is given in cond_var.wait(mutex) is because the wait function temporarily unlocks the mutex while it is waiting, and then it re-locks the mutex before it returns. The unlock is necessary so that a producer thread will be allowed to make the condition become true. Re-locking is needed to guarantee that the condition still will be true when the consumer accesses the shared data.
The third thing to note is that the consumer does not wait() if the condition already is true. A common newbie mistake is to unconditionally call cv.wait() and expect that a cv.notify() call in some other thread will wake it up. But a notify() will not wake the consumer thread if it happens before the consumer starts waiting.
Writing the "producer" is easier. There's no technical reason why a "producer" can't just call cond_var.notify() without doing anything else at all. But that's not very useful. Most producers do something like this:
mutex.lock();
... Do something that makes SomeImportantCondition() return true;
cond_var.notify();
mutex.unlock();
The only really important thing is that the producer locks the mutex before it touches the shared data that are tested by SomeImportantCondition(). Some programming languages will let you move the notify() call after the unlock() call. Others won't. It doesn't really matter either way.

How does Mutex lock work in this question?

currently receive this question in interview and tried to solve it but unfortunately not very well with Mutex.
Mutex A;
Mutex B;
char kFirstString[13] = "First Value.";
char kSecondString[14] = "Second Value.";
void Thread1() {
A.Lock();
B.Lock();
strcpy(kFirstString, argv[1]);
printf("%s\n", kFirstString);
B.Unlock();
A.Unlock();
}
void Thread2() {
B.Lock();
A.Lock();
printf("%s\n", kSecondString);
A.Unlock();
B.Unlock();
}
In thread1 strcpy(kFirstString, argv[1]); will print the content of argv[1]
, but what the thread2 prints printf("%s\n", kSecondString); is not sure, it might be some garbage content, that is my guess. Please point out if my thought is wrong.
And I think this function might have dead-lock since Mute A is hold by thread1 while thread2 trying to get A, as well as the similar situation of B.
It is not a given that this will deadlock. If the sequence of two locks is not interrupted by the other thread, there is no problem. However, you are on the right track.
One problem is that there is a possibility of deadlock, in a scenario such as this:
Thread1 acquires lock on A
Thread2 acquires lock on B
in any order; then
Thread1 tries to acquire lock on B, but fails since Thread2 has it, and waits
Thread2 tries to acquire lock on A, but fails since Thread1 has it, and waits
in any order. This is a deadlock. It is not certain (and in a non-toy scenario, not even probable) that the two threads will run with such timing to interrupt each other at this precise moment, but it is possible — which is even more dangerous, because it will pass testing many times and fail unpredictably at a random point in time. You want your code to have 0% chance of deadlock; "improbable" is not good enough.
Since this seems to be C, the other problem seems to be that there is no check to indicate whether argv[1] exists, and whether it would fit inside kFirstString; if the program is invoked with no arguments, or if the first argument is too long, trouble ensues. This is entirely unrelated with threads or mutexes, though.

Does a lock on a mutex also apply to called functions?

If a mutex is defined within a function, does its lock apply to functions called from that function? ie
void f () {
Mutex mutex;
g();
}
Does the lock still apply to any data modifications in g()?
Also, am I right to say that a lock defined in a class method will only apply to specific instances of that class? Meaning:
Class Foo;
Foo foo1, foo2;
(In thread 1) foo1.bar();
(In thread 2) foo2.bar();
Would each call be able to occur concurrently?
It would be a nice bonus if someone could explain / point out links that explain the mechanism behind mutexes. Thanks! I am currently working with the Qt Thread library, if that information helps.
In your example you don't actually lock the mutex, so it will not prevent different threads to access the function at the same time. Also you declare the mutex locally inside the function, so that each function call uses a different local mutex object. Even if this mutex would be locked, each function call would lock a different mutex object, not preventing simultaneous access.
A better strategy would be a setup like this:
class A {
QMutex mutex;
void f() {
QMutexLocker ml(mutex); // Acquire a lock on mutex
g();
// The lock on the mutex will be released when ml is destroyed.
// This happens at the end of this function.
}
// ...
};
In this case mutex is locked as long as ml exists, so also during the time the thread spends inside g(). If another thread would call f() during this time it would block in the creation of its ml object until the first thread left the function and the new thread can get the lock on mutex.
A mutex is something you grab, and will stop any other threads trying to grab it until you release it from the grabbing thread.
In your question, you have a function f allocating a Mutex instance. That is not enough to lock it. You have to specifically call mutex.lock() (in Qt, but also in general, unless you use pthread, in that case use pthread_mutex_lock and have fun with low level, platform dependent stuff. Qt abstracts it very well).
here is an example with Qt
void MyClass::doStuff( int c )
{
mutex.lock();
a = c;
b = c * 2;
mutex.unlock();
}
Once you get the lock, the call to g() will be done from the thread who got the lock, so it will be alone in that call assuming that you are not calling g() from other threads from another part of the code. Locking does not mean that it will stop all the other threads. It will stop threads trying to get the same lock, until the lock is released.
If that is the only way for your threads to reach g(), then you are synchronized on that access.
For the second part of your question, If the mutex is an instance attribute, then they will be two different mutexes. You will have to declare and instantiate a class mutex instance and refer to it foro your locking. In that case, any attempt to call a method in the class that locks the class mutex will be effectively synchronized, meaning that no two threads will execute that method together.
For example (I don't have Qt, so I cannot compile this code, and I stopped coding with it 2 years ago, so it could not work)
class Foo {
public:
void method(void) {
mutex.lock();
cout << "method called";
// long computation
mutex.unlock();
}
private:
QMutex mutex;
};
Ok, in this case, suppose you have two threads, 1 and 2, and two instances of the class Foo, a and b. Suppose that thread 1 calls a.method() and thread 2 calls b.method(). In this case, the two mutexes are different instances, so each thread will execute the call, independently, and run in parallel.
Suppose you have two threads, 1 and 2, and one instance of the class Foo which is shared between the two threads. if thread 1 calls a.method() and then thread 2 calls a.method(), thread 2 will stop and wait until the mutex lock is released.
Finally,
class Foo {
public:
void method(void) {
mutex.lock();
cout << "method called";
// long computation
mutex.unlock();
}
private:
static QMutex mutex;
};
QMutex Foo::mutex;
In this case, the mutex is a class static variable. You have only one instance of the mutex for each object instance. Suppose you had the same situation as the first case above: two threads, and two instances. In this case, when the second thread tries to call b.method() it will have to wait for a.method() to be completed by the first thread, as the lock is now unique and shared among all instances of your class.
For more info, Qt has a nice tutorial on multithreading
https://doc.qt.io/qt-5/threads.html
Your mutex is instatiated locally, on the stack. So a call to f() from one thread will be lock its own instance of the mutex. Any other call to f() from another thread will lock its own. So a race condition could occur with data accessed from g() ! Even tough you call it on the same class instance:
MyClass foo;
(In thread 1) foo->f();
(In thread 2) foo->f();
How to better handle lock depends on what you want to do. According to what you told I guess a better policy would be to modify g() implementation directly: it must lock a mutex declared as global for instance, or as being static in g() to be shared among any call to g(). As long as I understand you want to lock your data globally?

What is a mutex?

A mutex is a programming concept that is frequently used to solve multi-threading problems. My question to the community:
What is a mutex and how do you use it?
When I am having a big heated discussion at work, I use a rubber chicken which I keep in my desk for just such occasions. The person holding the chicken is the only person who is allowed to talk. If you don't hold the chicken you cannot speak. You can only indicate that you want the chicken and wait until you get it before you speak. Once you have finished speaking, you can hand the chicken back to the moderator who will hand it to the next person to speak. This ensures that people do not speak over each other, and also have their own space to talk.
Replace Chicken with Mutex and person with thread and you basically have the concept of a mutex.
Of course, there is no such thing as a rubber mutex. Only rubber chicken. My cats once had a rubber mouse, but they ate it.
Of course, before you use the rubber chicken, you need to ask yourself whether you actually need 5 people in one room and would it not just be easier with one person in the room on their own doing all the work. Actually, this is just extending the analogy, but you get the idea.
A Mutex is a Mutually exclusive flag. It acts as a gate keeper to a section of code allowing one thread in and blocking access to all others. This ensures that the code being controlled will only be hit by a single thread at a time. Just be sure to release the mutex when you are done. :)
Mutual Exclusion. Here's the Wikipedia entry on it.
The point of a mutex is to synchronize two threads. When you have two threads attempting to access a single resource, the general pattern is to have the first block of code attempting access to set the mutex before entering the code. When the second code block attempts access, it sees that the mutex is set and waits until the first block of code is complete (and unsets the mutex), then continues.
Specific details of how this is accomplished obviously varies greatly by programming language.
When you have a multi-threaded application, the different threads sometimes share a common resource, such as a variable or similar. This shared source often cannot be accessed at the same time, so a construct is needed to ensure that only one thread is using that resource at a time.
The concept is called "mutual exclusion" (short Mutex), and is a way to ensure that only one thread is allowed inside that area, using that resource etc.
How to use them is language specific, but is often (if not always) based on a operating system mutex.
Some languages doesn't need this construct, due to the paradigm, for example functional programming (Haskell, ML are good examples).
What is a Mutex?
The mutex (In fact, the term mutex is short for mutual exclusion) also known as spinlock is the simplest synchronization tool that is used to protect critical regions and thus prevent race conditions. That is a thread must acquire a lock before entering into a critical section (In critical section multi threads share a common variable, updating a table, writing a file and so on), it releases the lock when it leaves critical section.
What is a Race Condition?
A race condition occurs when two or more threads can access shared data and they try to change it at the same time. Because the thread scheduling algorithm can swap between threads at any time, you don't know the order in which the threads will attempt to access the shared data. Therefore, the result of the change in data is dependent on the thread scheduling algorithm, i.e. both threads are "racing" to access/change the data.
Real life example:
When I am having a big heated discussion at work, I use a rubber
chicken which I keep in my desk for just such occasions. The person
holding the chicken is the only person who is allowed to talk. If you
don't hold the chicken you cannot speak. You can only indicate that
you want the chicken and wait until you get it before you speak. Once
you have finished speaking, you can hand the chicken back to the
moderator who will hand it to the next person to speak. This ensures
that people do not speak over each other, and also have their own
space to talk.
Replace Chicken with Mutex and person with thread and you basically have the concept of a mutex.
#Xetius
Usage in C#:
This example shows how a local Mutex object is used to synchronize access to a protected resource. Because each calling thread is blocked until it acquires ownership of the mutex, it must call the ReleaseMutex method to release ownership of the thread.
using System;
using System.Threading;
class Example
{
// Create a new Mutex. The creating thread does not own the mutex.
private static Mutex mut = new Mutex();
private const int numIterations = 1;
private const int numThreads = 3;
static void Main()
{
// Create the threads that will use the protected resource.
for(int i = 0; i < numThreads; i++)
{
Thread newThread = new Thread(new ThreadStart(ThreadProc));
newThread.Name = String.Format("Thread{0}", i + 1);
newThread.Start();
}
// The main thread exits, but the application continues to
// run until all foreground threads have exited.
}
private static void ThreadProc()
{
for(int i = 0; i < numIterations; i++)
{
UseResource();
}
}
// This method represents a resource that must be synchronized
// so that only one thread at a time can enter.
private static void UseResource()
{
// Wait until it is safe to enter.
Console.WriteLine("{0} is requesting the mutex",
Thread.CurrentThread.Name);
mut.WaitOne();
Console.WriteLine("{0} has entered the protected area",
Thread.CurrentThread.Name);
// Place code to access non-reentrant resources here.
// Simulate some work.
Thread.Sleep(500);
Console.WriteLine("{0} is leaving the protected area",
Thread.CurrentThread.Name);
// Release the Mutex.
mut.ReleaseMutex();
Console.WriteLine("{0} has released the mutex",
Thread.CurrentThread.Name);
}
}
// The example displays output like the following:
// Thread1 is requesting the mutex
// Thread2 is requesting the mutex
// Thread1 has entered the protected area
// Thread3 is requesting the mutex
// Thread1 is leaving the protected area
// Thread1 has released the mutex
// Thread3 has entered the protected area
// Thread3 is leaving the protected area
// Thread3 has released the mutex
// Thread2 has entered the protected area
// Thread2 is leaving the protected area
// Thread2 has released the mutex
MSDN Reference Mutex
There are some great answers here, here is another great analogy for explaining what mutex is:
Consider single toilet with a key. When someone enters, they take the key and the toilet is occupied. If someone else needs to use the toilet, they need to wait in a queue. When the person in the toilet is done, they pass the key to the next person in queue. Make sense, right?
Convert the toilet in the story to a shared resource, and the key to a mutex. Taking the key to the toilet (acquire a lock) permits you to use it. If there is no key (the lock is locked) you have to wait. When the key is returned by the person (release the lock) you're free to acquire it now.
In C#, the common mutex used is the Monitor. The type is 'System.Threading.Monitor'. It may also be used implicitly via the 'lock(Object)' statement. One example of its use is when constructing a Singleton class.
private static readonly Object instanceLock = new Object();
private static MySingleton instance;
public static MySingleton Instance
{
lock(instanceLock)
{
if(instance == null)
{
instance = new MySingleton();
}
return instance;
}
}
The lock statement using the private lock object creates a critical section. Requiring each thread to wait until the previous is finished. The first thread will enter the section and initialize the instance. The second thread will wait, get into the section, and get the initialized instance.
Any sort of synchronization of a static member may use the lock statement similarly.
To understand MUTEX at first you need to know what is "race condition" and then only you will understand why MUTEX is needed. Suppose you have a multi-threading program and you have two threads. Now, you have one job in the job queue. The first thread will check the job queue and after finding the job it will start executing it. The second thread will also check the job queue and find that there is one job in the queue. So, it will also assign the same job pointer. So, now what happens, both the threads are executing the same job. This will cause a segmentation fault. This is the example of a race condition.
The solution to this problem is MUTEX. MUTEX is a kind of lock which locks one thread at a time. If another thread wants to lock it, the thread simply gets blocked.
The MUTEX topic in this pdf file link is really worth reading.
Mutexes are useful in situations where you need to enforce exclusive access to a resource accross multiple processes, where a regular lock won't help since it only works accross threads.
Mutex: Mutex stands for Mutual Exclusion. It means only one process/thread can enter into critical section at a given time. In concurrent programming multiple threads/process updating the shared resource (any variable, shared memory etc.) may lead to some unexpected result. ( As the result depends upon the which thread/process gets the first access).
In order to avoid such an unexpected result we need some synchronization mechanism, which ensures that only one thread/process gets access to such a resource at a time.
pthread library provides support for Mutex.
typedef union
{
struct __pthread_mutex_s
{
***int __lock;***
unsigned int __count;
int __owner;
#ifdef __x86_64__
unsigned int __nusers;
#endif
int __kind;
#ifdef __x86_64__
short __spins;
short __elision;
__pthread_list_t __list;
# define __PTHREAD_MUTEX_HAVE_PREV 1
# define __PTHREAD_SPINS 0, 0
#else
unsigned int __nusers;
__extension__ union
{
struct
{
short __espins;
short __elision;
# define __spins __elision_data.__espins
# define __elision __elision_data.__elision
# define __PTHREAD_SPINS { 0, 0 }
} __elision_data;
__pthread_slist_t __list;
};
#endif
This is the structure for mutex data type i.e pthread_mutex_t.
When mutex is locked, __lock set to 1. When it is unlocked __lock set to 0.
This ensure that no two processes/threads can access the critical section at same time.

What is a semaphore?

A semaphore is a programming concept that is frequently used to solve multi-threading problems. My question to the community:
What is a semaphore and how do you use it?
Think of semaphores as bouncers at a nightclub. There are a dedicated number of people that are allowed in the club at once. If the club is full no one is allowed to enter, but as soon as one person leaves another person might enter.
It's simply a way to limit the number of consumers for a specific resource. For example, to limit the number of simultaneous calls to a database in an application.
Here is a very pedagogic example in C# :-)
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace TheNightclub
{
public class Program
{
public static Semaphore Bouncer { get; set; }
public static void Main(string[] args)
{
// Create the semaphore with 3 slots, where 3 are available.
Bouncer = new Semaphore(3, 3);
// Open the nightclub.
OpenNightclub();
}
public static void OpenNightclub()
{
for (int i = 1; i <= 50; i++)
{
// Let each guest enter on an own thread.
Thread thread = new Thread(new ParameterizedThreadStart(Guest));
thread.Start(i);
}
}
public static void Guest(object args)
{
// Wait to enter the nightclub (a semaphore to be released).
Console.WriteLine("Guest {0} is waiting to entering nightclub.", args);
Bouncer.WaitOne();
// Do some dancing.
Console.WriteLine("Guest {0} is doing some dancing.", args);
Thread.Sleep(500);
// Let one guest out (release one semaphore).
Console.WriteLine("Guest {0} is leaving the nightclub.", args);
Bouncer.Release(1);
}
}
}
The article Mutexes and Semaphores Demystified by Michael Barr is a great short introduction into what makes mutexes and semaphores different, and when they should and should not be used. I've excerpted several key paragraphs here.
The key point is that mutexes should be used to protect shared resources, while semaphores should be used for signaling. You should generally not use semaphores to protect shared resources, nor mutexes for signaling. There are issues, for instance, with the bouncer analogy in terms of using semaphores to protect shared resources - you can use them that way, but it may cause hard to diagnose bugs.
While mutexes and semaphores have some similarities in their implementation, they should always be used differently.
The most common (but nonetheless incorrect) answer to the question posed at the top is that mutexes and semaphores are very similar, with the only significant difference being that semaphores can count higher than one. Nearly all engineers seem to properly understand that a mutex is a binary flag used to protect a shared resource by ensuring mutual exclusion inside critical sections of code. But when asked to expand on how to use a "counting semaphore," most engineers—varying only in their degree of confidence—express some flavor of the textbook opinion that these are used to protect several equivalent resources.
...
At this point an interesting analogy is made using the idea of bathroom keys as protecting shared resources - the bathroom. If a shop has a single bathroom, then a single key will be sufficient to protect that resource and prevent multiple people from using it simultaneously.
If there are multiple bathrooms, one might be tempted to key them alike and make multiple keys - this is similar to a semaphore being mis-used. Once you have a key you don't actually know which bathroom is available, and if you go down this path you're probably going to end up using mutexes to provide that information and make sure you don't take a bathroom that's already occupied.
A semaphore is the wrong tool to protect several of the essentially same resource, but this is how many people think of it and use it. The bouncer analogy is distinctly different - there aren't several of the same type of resource, instead there is one resource which can accept multiple simultaneous users. I suppose a semaphore can be used in such situations, but rarely are there real-world situations where the analogy actually holds - it's more often that there are several of the same type, but still individual resources, like the bathrooms, which cannot be used this way.
...
The correct use of a semaphore is for signaling from one task to another. A mutex is meant to be taken and released, always in that order, by each task that uses the shared resource it protects. By contrast, tasks that use semaphores either signal or wait—not both. For example, Task 1 may contain code to post (i.e., signal or increment) a particular semaphore when the "power" button is pressed and Task 2, which wakes the display, pends on that same semaphore. In this scenario, one task is the producer of the event signal; the other the consumer.
...
Here an important point is made that mutexes interfere with real time operating systems in a bad way, causing priority inversion where a less important task may be executed before a more important task because of resource sharing. In short, this happens when a lower priority task uses a mutex to grab a resource, A, then tries to grab B, but is paused because B is unavailable. While it's waiting, a higher priority task comes along and needs A, but it's already tied up, and by a process that isn't even running because it's waiting for B. There are many ways to resolve this, but it most often is fixed by altering the mutex and task manager. The mutex is much more complex in these cases than a binary semaphore, and using a semaphore in such an instance will cause priority inversions because the task manager is unaware of the priority inversion and cannot act to correct it.
...
The cause of the widespread modern confusion between mutexes and semaphores is historical, as it dates all the way back to the 1974 invention of the Semaphore (capital "S", in this article) by Djikstra. Prior to that date, none of the interrupt-safe task synchronization and signaling mechanisms known to computer scientists was efficiently scalable for use by more than two tasks. Dijkstra's revolutionary, safe-and-scalable Semaphore was applied in both critical section protection and signaling. And thus the confusion began.
However, it later became obvious to operating system developers, after the appearance of the priority-based preemptive RTOS (e.g., VRTX, ca. 1980), publication of academic papers establishing RMA and the problems caused by priority inversion, and a paper on priority inheritance protocols in 1990, 3 it became apparent that mutexes must be more than just semaphores with a binary counter.
Mutex: resource sharing
Semaphore: signaling
Don't use one for the other without careful consideration of the side effects.
Mutex: exclusive-member access to a resource
Semaphore: n-member access to a resource
That is, a mutex can be used to syncronize access to a counter, file, database, etc.
A sempahore can do the same thing but supports a fixed number of simultaneous callers. For example, I can wrap my database calls in a semaphore(3) so that my multithreaded app will hit the database with at most 3 simultaneous connections. All attempts will block until one of the three slots opens up. They make things like doing naive throttling really, really easy.
Consider, a taxi that can accommodate a total of 3(rear)+2(front) persons including the driver. So, a semaphore allows only 5 persons inside a car at a time.
And a mutex allows only 1 person on a single seat of the car.
Therefore, Mutex is to allow exclusive access for a resource (like an OS thread) while a Semaphore is to allow access for n number of resources at a time.
#Craig:
A semaphore is a way to lock a
resource so that it is guaranteed that
while a piece of code is executed,
only this piece of code has access to
that resource. This keeps two threads
from concurrently accesing a resource,
which can cause problems.
This is not restricted to only one thread. A semaphore can be configured to allow a fixed number of threads to access a resource.
Semaphore can also be used as a ... semaphore.
For example if you have multiple process enqueuing data to a queue, and only one task consuming data from the queue. If you don't want your consuming task to constantly poll the queue for available data, you can use semaphore.
Here the semaphore is not used as an exclusion mechanism, but as a signaling mechanism.
The consuming task is waiting on the semaphore
The producing task are posting on the semaphore.
This way the consuming task is running when and only when there is data to be dequeued
There are two essential concepts to building concurrent programs - synchronization and mutual exclusion. We will see how these two types of locks (semaphores are more generally a kind of locking mechanism) help us achieve synchronization and mutual exclusion.
A semaphore is a programming construct that helps us achieve concurrency, by implementing both synchronization and mutual exclusion. Semaphores are of two types, Binary and Counting.
A semaphore has two parts : a counter, and a list of tasks waiting to access a particular resource. A semaphore performs two operations : wait (P) [this is like acquiring a lock], and release (V)[ similar to releasing a lock] - these are the only two operations that one can perform on a semaphore. In a binary semaphore, the counter logically goes between 0 and 1. You can think of it as being similar to a lock with two values : open/closed. A counting semaphore has multiple values for count.
What is important to understand is that the semaphore counter keeps track of the number of tasks that do not have to block, i.e., they can make progress. Tasks block, and add themselves to the semaphore's list only when the counter is zero. Therefore, a task gets added to the list in the P() routine if it cannot progress, and "freed" using the V() routine.
Now, it is fairly obvious to see how binary semaphores can be used to solve synchronization and mutual exclusion - they are essentially locks.
ex. Synchronization:
thread A{
semaphore &s; //locks/semaphores are passed by reference! think about why this is so.
A(semaphore &s): s(s){} //constructor
foo(){
...
s.P();
;// some block of code B2
...
}
//thread B{
semaphore &s;
B(semaphore &s): s(s){} //constructor
foo(){
...
...
// some block of code B1
s.V();
..
}
main(){
semaphore s(0); // we start the semaphore at 0 (closed)
A a(s);
B b(s);
}
In the above example, B2 can only execute after B1 has finished execution. Let's say thread A comes executes first - gets to sem.P(), and waits, since the counter is 0 (closed). Thread B comes along, finishes B1, and then frees thread A - which then completes B2. So we achieve synchronization.
Now let's look at mutual exclusion with a binary semaphore:
thread mutual_ex{
semaphore &s;
mutual_ex(semaphore &s): s(s){} //constructor
foo(){
...
s.P();
//critical section
s.V();
...
...
s.P();
//critical section
s.V();
...
}
main(){
semaphore s(1);
mutual_ex m1(s);
mutual_ex m2(s);
}
The mutual exclusion is quite simple as well - m1 and m2 cannot enter the critical section at the same time. So each thread is using the same semaphore to provide mutual exclusion for its two critical sections. Now, is it possible to have greater concurrency? Depends on the critical sections. (Think about how else one could use semaphores to achieve mutual exclusion.. hint hint : do i necessarily only need to use one semaphore?)
Counting semaphore: A semaphore with more than one value. Let's look at what this is implying - a lock with more than one value?? So open, closed, and ...hmm. Of what use is a multi-stage-lock in mutual exclusion or synchronization?
Let's take the easier of the two:
Synchronization using a counting semaphore: Let's say you have 3 tasks - #1 and 2 you want executed after 3. How would you design your synchronization?
thread t1{
...
s.P();
//block of code B1
thread t2{
...
s.P();
//block of code B2
thread t3{
...
//block of code B3
s.V();
s.V();
}
So if your semaphore starts off closed, you ensure that t1 and t2 block, get added to the semaphore's list. Then along comes all important t3, finishes its business and frees t1 and t2. What order are they freed in? Depends on the implementation of the semaphore's list. Could be FIFO, could be based some particular priority,etc. (Note : think about how you would arrange your P's and V;s if you wanted t1 and t2 to be executed in some particular order, and if you weren't aware of the implementation of the semaphore)
(Find out : What happens if the number of V's is greater than the number of P's?)
Mutual Exclusion Using counting semaphores: I'd like you to construct your own pseudocode for this (makes you understand things better!) - but the fundamental concept is this : a counting semaphore of counter = N allows N tasks to enter the critical section freely. What this means is you have N tasks (or threads, if you like) enter the critical section, but the N+1th task gets blocked (goes on our favorite blocked-task list), and only is let through when somebody V's the semaphore at least once. So the semaphore counter, instead of swinging between 0 and 1, now goes between 0 and N, allowing N tasks to freely enter and exit, blocking nobody!
Now gosh, why would you need such a stupid thing? Isn't the whole point of mutual exclusion to not let more than one guy access a resource?? (Hint Hint...You don't always only have one drive in your computer, do you...?)
To think about : Is mutual exclusion achieved by having a counting semaphore alone? What if you have 10 instances of a resource, and 10 threads come in (through the counting semaphore) and try to use the first instance?
I've created the visualization which should help to understand the idea. Semaphore controls access to a common resource in a multithreading environment.
ExecutorService executor = Executors.newFixedThreadPool(7);
Semaphore semaphore = new Semaphore(4);
Runnable longRunningTask = () -> {
boolean permit = false;
try {
permit = semaphore.tryAcquire(1, TimeUnit.SECONDS);
if (permit) {
System.out.println("Semaphore acquired");
Thread.sleep(5);
} else {
System.out.println("Could not acquire semaphore");
}
} catch (InterruptedException e) {
throw new IllegalStateException(e);
} finally {
if (permit) {
semaphore.release();
}
}
};
// execute tasks
for (int j = 0; j < 10; j++) {
executor.submit(longRunningTask);
}
executor.shutdown();
Output
Semaphore acquired
Semaphore acquired
Semaphore acquired
Semaphore acquired
Could not acquire semaphore
Could not acquire semaphore
Could not acquire semaphore
Sample code from the article
A semaphore is an object containing a natural number (i.e. a integer greater or equal to zero) on which two modifying operations are defined. One operation, V, adds 1 to the natural. The other operation, P, decreases the natural number by 1. Both activities are atomic (i.e. no other operation can be executed at the same time as a V or a P).
Because the natural number 0 cannot be decreased, calling P on a semaphore containing a 0 will block the execution of the calling process(/thread) until some moment at which the number is no longer 0 and P can be successfully (and atomically) executed.
As mentioned in other answers, semaphores can be used to restrict access to a certain resource to a maximum (but variable) number of processes.
A hardware or software flag. In multi tasking systems , a semaphore is as variable with a value that indicates the status of a common resource.A process needing the resource checks the semaphore to determine the resources status and then decides how to proceed.
Semaphores are act like thread limiters.
Example: If you have a pool of 100 threads and you want to perform some DB operation. If 100 threads access the DB at a given time, then there may be locking issue in DB so we can use semaphore which allow only limited thread at a time.Below Example allow only one thread at a time. When a thread call the acquire() method, it will then get the access and after calling the release() method, it will release the acccess so that next thread will get the access.
package practice;
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static void main(String[] args) {
Semaphore s = new Semaphore(1);
semaphoreTask s1 = new semaphoreTask(s);
semaphoreTask s2 = new semaphoreTask(s);
semaphoreTask s3 = new semaphoreTask(s);
semaphoreTask s4 = new semaphoreTask(s);
semaphoreTask s5 = new semaphoreTask(s);
s1.start();
s2.start();
s3.start();
s4.start();
s5.start();
}
}
class semaphoreTask extends Thread {
Semaphore s;
public semaphoreTask(Semaphore s) {
this.s = s;
}
#Override
public void run() {
try {
s.acquire();
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+" Going to perform some operation");
s.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
So imagine everyone is trying to go to the bathroom and there's only a certain number of keys to the bathroom. Now if there's not enough keys left, that person needs to wait. So think of semaphore as representing those set of keys available for bathrooms (the system resources) that different processes (bathroom goers) can request access to.
Now imagine two processes trying to go to the bathroom at the same time. That's not a good situation and semaphores are used to prevent this. Unfortunately, the semaphore is a voluntary mechanism and processes (our bathroom goers) can ignore it (i.e. even if there are keys, someone can still just kick the door open).
There are also differences between binary/mutex & counting semaphores.
Check out the lecture notes at http://www.cs.columbia.edu/~jae/4118/lect/L05-ipc.html.
This is an old question but one of the most interesting uses of semaphore is a read/write lock and it has not been explicitly mentioned.
The r/w locks works in simple fashion: consume one permit for a reader and all permits for writers.
Indeed, a trivial implementation of a r/w lock but requires metadata modification on read (actually twice) that can become a bottle neck, still significantly better than a mutex or lock.
Another downside is that writers can be started rather easily as well unless the semaphore is a fair one or the writes acquire permits in multiple requests, in such case they need an explicit mutex between themselves.
Further read:
Mutex is just a boolean while semaphore is a counter.
Both are used to lock part of code so it's not accessed by too many threads.
Example
lock.set()
a += 1
lock.unset()
Now if lock was a mutex, it means that it will always be locked or unlocked (a boolean under the surface) regardless how many threads try access the protected snippet of code. While locked, any other thread would just wait until it's unlocked/unset by the previous thread.
Now imagine if instead lock was under the hood a counter with a predefined MAX value (say 2 for our example). Then if 2 threads try to access the resource, then lock would get its value increased to 2. If a 3rd thread then tried to access it, it would simply wait for the counter to go below 2 and so on.
If lock as a semaphore had a max of 1, then it would be acting exactly as a mutex.
A semaphore is a way to lock a resource so that it is guaranteed that while a piece of code is executed, only this piece of code has access to that resource. This keeps two threads from concurrently accesing a resource, which can cause problems.

Resources