Here in the below code we are locking m1 first in thread t1 and m2 first in thread t2. Now to lock m2 in thread t1 it will be waiting for t2 to unlock, which never happens. That is a deadlock situation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<thread> | |
#include<mutex> | |
#include<iostream> | |
using namepspace std; | |
void print(const std::string &s) | |
{ | |
cout << s << endl; | |
} | |
int main() { | |
std::mutex m1; | |
std::mutex m2; | |
std::thread t1([&] { | |
print("From T1"); | |
m1.lock(); //locking m1 first | |
print("From T1"); | |
m2.lock(); //locking m2 second | |
}); | |
std::thread t2([&] { | |
print("From T2"); | |
m2.lock(); //lcoking m2 first | |
print("From T2"); | |
m1.lock(); //locking m1 second | |
}); | |
t1.join(); | |
t2.join(); | |
} |
To avoid this situation
- Prefer locking single mutex at a time
- Avoid locking a mutex and then calling a user provided function, because the user provided function might crash and we may never be able to unlock it.
- Use std::lock() to lock more than one mutex.
- Lock the mutex in same order.
No comments:
Post a Comment