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.
Related
I am trying to pause my thread waiting for an user action. I know I could use Qt::BlockingQueuedConnection but that is not the point here. I would like to use QWaitCondition but I don't understand in this particular case why I need a QMutex.
Consider this code :
class MyWorker: public QThread
{
private:
QMutex mDummy;
QWaitCondition mStep1;
void doStuff1(){}
void doStuff2(){}
signals:
void step1Finished();
public:
MyWorker(...): {}
protected:
void run()
{
doStuff1();
emit step1Finished();
mDummy.lock();
mStep1.wait(mDummy);
mDummy.unlock();
doStuff2();
}
}
In this case the QMutex mDummy seems useless to me. I use it only because wait() need it as parameter.
I know that wait() unlock the mutex then (re)lock it after waking up, but why there no possibility to use wait() without it?
First of all, wait condition needs a mutex, so you gotta give it one. That's what a wait condition is. It is the most low level signalling mechanism between threads in multi-threading, so it doesn't provide the "convenience" you seem to be looking for.
But you also need the mutex to get things work right. A wait condition might have a spurious wakeup, that is it could be woken up for "no reason" (google "wait condition spurious wakeup" to learn more). So you have to have some condition in there to check, and keep waiting if it's still not time to continue. And to avoid race conditions, that check has to be protected by mutex.
Snippets:
// wait
mDummy.lock();
mStopWaiting = false; // maybe here, if you want to make sure this waits in all cases
while (!mStopWaiting)
{
// note that wait releases the mutex while waiting
mStep1.wait(&mDummy);
}
mDummy.unlock();
// signal end of wait
mDummy.lock();
mStopWaiting = true;
mStep1.wakeOne(); // or wakeAll() maybe depending on other code
mDummy.unlock();
As you can see, that mutex isn't so dummy after all. Note that all access to mStopWaiting has to be protected by this mutex, not just here.
Imagine you want to wait for something to happen. Since that something has to happen in another thread (since this thread is waiting) it has to be protected in some way to avoid race conditions.
Imagine you use the following code:
Acquire a lock.
Check if the thing you want to wait for has happened.
If it has, stop, you're done.
If it hasn't, wait.
Oops. We're still holding the lock. There's no way the thing we're waiting for can happen because no other thread can access it.
Let's try again.
Acquire a lock.
Check if the thing you want to wait for has happened.
If it has, stop, you're done.
If it hasn't, release the lock and wait.
Oops. What if after we release the lock but before we wait, it happens. Then we'll be waiting for something that already happened.
So what we need for step 4 is an atomic "unlock and wait" operation. This releases the lock and waits without giving another thread a chance to sneak in and change things before we can start waiting.
If you don't need an atomic "unlock and wait" operation, don't use QWaitCondition. This is its sole purpose. It takes a QMutex so it knows what to unlock. That QMutex must protect whatever it is the thread is waiting for or your code will be vulnerable to the very race condition QWaitCondition exists to solve for you.
TL;DR
Why does std::condition_variable::wait needs a mutex as one of its variables?
Answer 1
You may look a the documentation and quote that:
wait... Atomically releases lock
But that's not a real reason. That's just validate my question even more: why does it need it in the first place?
Answer 2
predicate is most likely query the state of a shared resource and it must be lock guarded.
OK. fair.
Two questions here
Is it always true that predicate query the state of a shared resource? I assume yes. I t doesn't make sense to me to implement it otherwise
What if I do not pass any predicate (it is optional)?
Using predicate - lock makes sense
int i = 0;
void waits()
{
std::unique_lock<std::mutex> lk(cv_m);
cv.wait(lk, []{return i == 1;});
std::cout << i;
}
Not Using predicate - why can't we lock after the wait?
int i = 0;
void waits()
{
cv.wait(lk);
std::unique_lock<std::mutex> lk(cv_m);
std::cout << i;
}
Notes
I know that there are no harmful implications to this practice. I just don't know how to explain to my self why it was design this way?
Question
If predicate is optional and is not passed to wait, why do we need the lock?
When using a condition variable to wait for a condition, a thread performs the following sequence of steps:
It determines that the condition is not currently true.
It starts waiting for some other thread to make the condition true. This is the wait call.
For example, the condition might be that a queue has elements in it, and a thread might see that the queue is empty and wait for another thread to put things in the queue.
If another thread were to intercede between these two steps, it could make the condition true and notify on the condition variable before the first thread actually starts waiting. In this case, the waiting thread would not receive the notification, and it might never stop waiting.
The purpose of requiring the lock to be held is to prevent other threads from interceding like this. Additionally, the lock must be unlocked to allow other threads to do whatever we're waiting for, but it can't happen before the wait call because of the notify-before-wait problem, and it can't happen after the wait call because we can't do anything while we're waiting. It has to be part of the wait call, so wait has to know about the lock.
Now, you might look at the notify_* methods and notice that those methods don't require the lock to be held, so there's nothing actually stopping another thread from notifying between steps 1 and 2. However, a thread calling notify_* is supposed to hold the lock while performing whatever action it does to make the condition true, which is usually enough protection.
TL;DR
If predicate is optional and is not passed to wait, why do we need the lock?
condition_variable is designed to wait for a certain condition to come true, not to wait just for a notification. So to "catch" the "moment" when the condition becomes true you need to check the condition and wait for the notification. And to avoid a race condition you need those two to be a single atomic operation.
Purpose Of condition_variable:
Enable a program to implement this: do some action when a condition C holds.
Intended Protocol:
Condition producer changes state of the world from !C to C.
Condition consumer waits for C to happen and takes the action while/after condition C holds.
Simplification:
For simplicity (to limit number of cases to think of) let's assume that C never switches back to !C. Let's also forget about spurious wakeups. Even with this assumptions we'll see that the lock is necessary.
Naive Approach:
Let's have two threads with an essential code summarized like this:
void producer() {
_condition = true;
_condition_variable.notify_all();
}
void consumer() {
if (!_condition) {
_condition_variable.wait();
}
action();
}
The Problem:
The problem here is a race condition. A problematic interleaving of the threads is following:
The consumer reads condition, checks it to be false and decides to wait.
A thread scheduler interrupts consumer and resumes producer.
The producer updates condition to become true and invokes notify_all().
The consumer is resumed.
The consumer actually does wait(), but is never notified and waken up (a liveness hazard).
So without locking the consumer may miss the event of the condition becoming true.
Solution:
Disclaimer: this code still does not handle spurious wakeups and possibility of condition becoming false again.
void producer() {
{ std::unique_lock<std::mutex> l(_mutex);
_condition = true;
}
_condition_variable.notify_all();
}
void consumer() {
{ std::unique_lock<std::mutex> l(_mutex);
if (!_condition) {
_condition_variable.wait(l);
}
}
action();
}
Here we check condition, release lock and start waiting as a single atomic operation, preventing the race condition mentioned before.
See Also
Why Lock condition await must hold the lock
You need a std::unique_lock when using std::condition_variable for the same reason you need a std::FILE* when using std::fwrite and for the same reason a BasicLockable is necessary when using std::unique_lock itself.
The feature std::fwrite gives you, entire the reason it exists, is to write to files. So you have to give it a file. The feature std::unique_lock provides you is RAII locking and unlocking of a mutex (or another BasicLockable, like std::shared_mutex, etc.) so you have to give it something to lock and unlock.
The feature std::condition_variable provides, the entire reason it exists, is the atomically waiting and unlocking a lock (and completing a wait and locking). So you have to give it something to lock.
Why would someone want that is a separate question that has been discussed already. For example:
When is a condition variable needed, isn't a mutex enough?
Conditional Variable vs Semaphore
Advantages of using condition variables over mutex
And so on.
As has been explained, the pred parameter is optional, but having some sort of a predicate and testing it isn't. Or, in other words, not having a predicate doesn't make any sense inn a manner similar to how having a condition variable without a lock doesn't making any sense.
The reason you have a lock is because you have shared state you need to protect from simultaneous access. Some function of that shared state is the predicate.
If you don't have a predicate and you don't have a lock you really don't need a condition variable just like if you don't have a file you really don't need fwrite.
A final point is that the second code snippet you wrote is very broken. Obviously it won't compile as you define the lock after you try to pass it as an argument to condition_variable::wait(). You probably meant something like:
std::mutex mtx_cv;
std::condition_variable cv;
...
{
std::unique_lock<std::mutex> lk(mtx_cv);
cv.wait(lk);
lk.lock(); // throws std::system_error with an error code of std::errc::resource_deadlock_would_occur
}
The reason this is wrong is very simple. condition_variable::wait's effects are (from [thread.condition.condvar]):
Effects:
— Atomically calls lock.unlock() and blocks on *this.
— When unblocked, calls lock.lock() (possibly blocking on the lock), then returns.
— The function will unblock when signaled by a call to notify_one() or a call to notify_all(), or spuriously
After the return from wait() the lock is locked, and unique_lock::lock() throws an exception if it has already locked the mutex it wraps ([thread.lock.unique.locking]).
Again, why would someone want coupling waiting and locking the way std::condition_variable does is a separate question, but given that it does - you cannot, by definition, lock a std::condition_variable's std::unique_lock after std::condition_variable::wait has returned.
It's not stated in the documentation (and could be implemented differently) but conceptually you can imagine the condition variable has another mutex to both protect its own data but also coordinate the condition, waiting and notification with modification of the consumer code data (e.g. queue.size()) affecting the test.
So when you call wait(...) the following (logically) happens.
Precondition: The consumer code holds the lock (CCL) controlling the consumer condition data (CCD).
The condition is checked, if true, execution in the consumer code continues still holding the lock.
If false, it first acquires its own lock (CVL), adds the current thread to the waiting thread collection releases the consumer lock and puts itself to waiting and releases its own lock (CVL).
That final step is tricky because it needs to sleep the thread and release the CVL at the same time or in that order or in a way that threads notified just before going to wait are able to (somehow) not go to wait.
The step of acquiring the CVL before releasing the CCD is key. Any parallel thread trying to update the CCD and notify will be blocked either by the CCL or CVL. If the CCL was released before acquiring the CVL a parallel thread could acquire the CCL, change the data and then notify before the the to-be-waiting thread is added to the waiters.
A parallel thread acquires the CCL, modifies the data to make the condition true (or at least worth testing) and then notifies. Notification acquires the the CVL and identifies a blocked thread (or threads) if any to unwait. The unwaited threads then seek to acquire the CCL and may block there but won't leave wait and re-perform the test until they've acquired it.
Notification must acquire the CVL to make sure threads that have found the test false have been added to the waiters.
It's OK (possibly preferable for performance) to notify without holding the CCL because the hand-off between the CCL and CVL in the wait code is ensuring the ordering.
It may be preferrable because notifying when holding the CCL may mean all the unwaited threads just unwait to block (on the CCL) while the thread modifying the data is still holding the lock.
Notice that even if the CCD is atomic you must modify it holding the CCL or that Lock CVL, unlock CCL step won't ensure the total ordering required to make sure notifications aren't sent when threads are in the process of going to wait.
The standard only talks about atomicity of operations and another implementation may have a way of blocking notification before completing the 'add to waiters' step has completed following a failed test. The C++ Standard is careful to not dictate an implementation.
In all that, to answer some of the specific questions.
Must the state be shared? Sort of. There could be an external condition like a file being in a directory and the wait is timed to re-try after a time-period. You can decide for yourself whether you consider the file system or even just the wall-clock to be shared state.
Must there be any state? Not necessarily. A thread can wait on notification.
That could be tricky to coordinate because there has to be enough sequencing to stop the other thread notifying out of turn. The commonest solution is to have some boolean flag set by the notifying thread so the notified thread knows if it missed it. The normal use of void wait(std::unique_lock<std::mutex>& lk) is when the predicate is checked outside:
std::unique_lock<std::mutex> ulk(ccd_mutex)
while(!condition){
cv.wait(ulk);
}
Where the notifying thread uses:
{
std::lock_guard<std::mutex> guard(ccd_mutex);
condition=true;
}
cv.notify();
The reason is that in some times the waiting-thread holds the m_mutex:
#include <mutex>
#include <condition_variable>
void CMyClass::MyFunc()
{
std::unique_lock<std::mutex> guard(m_mutex);
// do something (on the protected resource)
m_condiotion.wait(guard, [this]() {return !m_bSpuriousWake; });
// do something else (on the protected resource)
guard.unluck();
// do something else than else
}
and a thread should never go to sleep while holding a m_mutex. One doesn't want to lock everybody out, while sleeping. So, atomically: {guard is unlocked and the thread go to sleep}. Once it waked up by the other-thread (m_condiotion.notify_one(), let's say) guard is locked again, and then the thread continue.
Reference (video)
Because if not so, there's a race condition before the waiting thread noticing the change of the shared state and the wait() call.
Assume we got a shared state of type std::atomic state_, there's still a fair chance for the waiting thread to miss a notification:
T1(waiting) | T2(notification)
---------------------------------------------- * ---------------------------
1) for (int i = state_; i != 0; i = state_) { |
2) | state_ = 0;
3) | cv.notify();
4) cv.wait(); |
5) }
6) // go on with the satisfied condition... |
Note that the wait() call failed to notice the latest value of state_ and may keep waiting forever.
I'm sure mutex isn't enough that's the reason the concept of condition variables exist; but it beats me and I'm not able to convince myself with a concrete scenario when a condition variable is essential.
Differences between Conditional variables, Mutexes and Locks question's accepted answer says that a condition variable is a
lock with a "signaling" mechanism. It is used when threads need to
wait for a resource to become available. A thread can "wait" on a CV
and then the resource producer can "signal" the variable, in which
case the threads who wait for the CV get notified and can continue
execution
Where I get confused is that, a thread can wait on a mutex too, and when it gets signalled, is simply means the variable is now available, why would I need a condition variable?
P.S.: Also, a mutex is required to guard the condition variable anyway, when makes my vision more askew towards not seeing condition variable's purpose.
Even though you can use them in the way you describe, mutexes weren't designed for use as a notification/synchronization mechanism. They are meant to provide mutually exclusive access to a shared resource. Using mutexes to signal a condition is awkward and I suppose would look something like this (where Thread1 is signaled by Thread2):
Thread1:
while(1) {
lock(mutex); // Blocks waiting for notification from Thread2
... // do work after notification is received
unlock(mutex); // Tells Thread2 we are done
}
Thread2:
while(1) {
... // do the work that precedes notification
unlock(mutex); // unblocks Thread1
lock(mutex); // lock the mutex so Thread1 will block again
}
There are several problems with this:
Thread2 cannot continue to "do the work that precedes notification" until Thread1 has finished with "work after notification". With this design, Thread2 is not even necessary, that is, why not move "work that precedes" and "work after notification" into the same thread since only one can run at a given time!
If Thread2 is not able to preempt Thread1, Thread1 will immediately re-lock the mutex when it repeats the while(1) loop and Thread1 will go about doing the "work after notification" even though there was no notification. This means you must somehow guarantee that Thread2 will lock the mutex before Thread1 does. How do you do that? Maybe force a schedule event by sleeping or by some other OS-specific means but even this is not guaranteed to work depending on timing, your OS, and the scheduling algorithm.
These two problems aren't minor, in fact, they are both major design flaws and latent bugs. The origin of both of these problems is the requirement that a mutex is locked and unlocked within the same thread. So how do you avoid the above problems? Use condition variables!
BTW, if your synchronization needs are really simple, you could use a plain old semaphore which avoids the additional complexity of condition variables.
Mutex is for exclusive access of shared resources, while conditional variable is about waiting for a condition to be true. They are tw different types of kernel resource. Some people might think they can implement conditional variable by themselves with mutex, a common pattern is "flag + mutex":
lock(mutex)
while (!flag) {
sleep(100);
}
unlock(mutex)
do_something_on_flag_set();
but it doesn't work, because you never release the mutex during the wait, no one else can set the flag in a thread-safe way. This is why we need kernel support for conditional variables, so when you're waiting on a condition variable, the associated mutex is not hold by your thread until it's signaled.
I was thinking about this too and the most important information which I think was missing everywhere is that mutex can be owned (or changed) by only one thread at a time. So if you have one producer and more consumers, the producer would have to wait on mutex to produce. With cond. variable it can produce at any time.
You need condition variables, to be used with a mutex (each cond.var. belongs to a mutex) to signal changing states (conditions) from one thread to another one. The idea is that a thread can wait till some condition becomes true. Such conditions are program specific (i.e. "queue is empty", "matrix is big", "some resource is almost exhausted", "some computation step has finished" etc). A mutex might have several related condition variables. And you need condition variables because such conditions may not always be expressed as simply as "a mutex is locked" (so you need to broadcast changes in conditions to other threads).
Read some good posix thread tutorials, e.g. this tutorial or that or that one. Better yet, read a good pthread book. See this question.
Also read Advanced Unix Programming and Advanced Linux Programming
P.S. Parallelism and threads are difficult concepts to grasp. Take time to read and experiment and read again.
The conditional var and the mutex pair can be replaced by a binary semaphore and mutex pair. The sequence of operations of a consumer thread when using the conditional var + mutex is:
Lock the mutex
Wait on the conditional var
Process
Unlock the mutex
The producer thread sequence of operations is
Lock the mutex
Signal the conditional var
Unlock the mutex
The corresponding consumer thread sequence when using the sema+mutex pair is
Wait on the binary sema
Lock the mutex
Check for the expected condition
If the condition is true, process.
Unlock the mutex
If the condition check in the step 3 was false, go back to the step 1.
The sequence for the producer thread is:
Lock the mutex
Post the binary sema
Unlock the mutex
As you can see the unconditional processing in the step 3 when using the conditional var is replaced by the conditional processing in the step 3 and step 4 when using the binary sema.
The reason is that when using sema+mutex, in a race condition, another consumer thread may sneak in between the step 1 and 2 and process/nullify the condition. This won't happen when using conditional var. When using the conditional var, the condition is guarantied to be true after the step 2.
The binary semaphore can be replaced with the regular counting semaphore. This may result in the step 6 to step 1 loop a few more times.
Slowjelj is right, but to shed some light on the problem, look at the python code below. We have a buffer, a producer, and a consumer. And think if you could rewrite it just with mutexes.
import threading, time, random
cv = threading.Condition()
buffer = []
MAX = 3
def put(value):
cv.acquire()
while len(buffer) == MAX:
cv.wait()
buffer.append(value)
print("added value ", value, "length =", len(buffer))
cv.notify()
cv.release()
def get():
cv.acquire()
while len(buffer) == 0:
cv.wait()
value = buffer.pop()
print("removed value ", value, "length =", len(buffer))
cv.notify()
cv.release()
def producer():
while True:
put(0) # it doesn't mater what is the value in our example
time.sleep(random.random()/10)
def consumer():
while True:
get()
time.sleep(random.random()/10)
if __name__ == '__main__':
cs = threading.Thread(target=consumer)
pd = threading.Thread(target=producer)
cs.start()
pd.start()
cs.join()
pd.join()
I think it is implementation defined.
The mutex is enough or not depends on whether you regard the mutex as a mechanism for critical sections or something more.
As mentioned in http://en.cppreference.com/w/cpp/thread/mutex/unlock,
The mutex must be locked by the current thread of execution, otherwise, the behavior is undefined.
which means a thread could only unlock a mutex which was locked/owned by itself in C++.
But in other programming languages, you might be able to share a mutex between processes.
So distinguishing the two concepts may be just performance considerations, a complex ownership identification or inter-process sharing are not worthy for simple applications.
For example, you may fix #slowjelj's case with an additional mutex (it might be an incorrect fix):
Thread1:
lock(mutex0);
while(1) {
lock(mutex0); // Blocks waiting for notification from Thread2
... // do work after notification is received
unlock(mutex1); // Tells Thread2 we are done
}
Thread2:
while(1) {
lock(mutex1); // lock the mutex so Thread1 will block again
... // do the work that precedes notification
unlock(mutex0); // unblocks Thread1
}
But your program will complain that you have triggered an assertion left by the compiler (e.g. "unlock of unowned mutex" in Visual Studio 2015).
When a thread has acquired the lock and execute the following code, Could the thread will unlock the lock it has acquired just with the return statement? some code like this.
static pthread_mutex_t mutex;
int foo()
{
pthread_mutex_lock(mutex);
.........
execute some code here and some errors happen
return -1;// but without pthread_mutex_unlock
pthread_mutex_unlock(mutext)
return 0;
}
Some errors happens before pthread_mutex_unlock statement and the thread returns to the callee. Will the thread give back the mutext lock for other threads without executing pthread_mutex_unlock?
No, the lock is not automatically released. This is why, in C++ code, it is common to use Resource Aquisition is Initialization (RAII), which takes advantage of construction/destruction to ensure that each call to the lock function has a corresponding call to unlock. If you are writing pure C code, though, you will need to make sure that you unlock the mutex, even in error situations, before returning.
Note that you can make your coding a little bit easier by doing the following:
static inline int some_function_critical_section_unsynchronized(void) {
// ...
}
int some_function(void) {
int status = 0;
pthread_mutex_lock(mutex);
status = some_function_critical_section_unsynchronized();
pthread_mutex_unlock(mutex);
return status;
}
In other words, if you can separate the logic into smaller functions, you may be able to tease out the locking code from your logic. Of course, sometimes this is not possible (like when coding in this fashion would make the critical section too large, and for performance, the less readable form is required).
If you can use C++, I would strongly suggest using boost::thread and boost::scoped_lock to ensure that the acquired mutex is automatically freed when its usage has gone out of scope.
No, it will not automatically unlock the mutex. You must explicitly call pthread_mutex_unlock() in the error path, if the mutex has been locked by the function.
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.