8.recursive Mutex
8.recursive Mutex
#multithreading
[[(thread)]] [[1.th.parameters]] [[2.th.&return]] [[3.th.lambda]] [[4.th.methods]]
[[5.mutex]] [[6.mutex.lock_guard]] [[7.Deadlock]] [[8.recursive_mutex]] [[9.
unique_lock]]
---
In multithreaded programming, a mutex is a synchronization primitive that helps
ensure mutual exclusion, i.e., only one thread can access a shared resource at any
given time. In C++, the standard library provides several types of mutexes,
including `std::mutex`, `std::timed_mutex`, and `std::recursive_mutex`.
Here's an example:
```cpp
#include <iostream>
#include <mutex>
#include <thread>
std::recursive_mutex mtx;
void foo(int n) {
mtx.lock();
std::cout << "Thread " << n << " entered foo." << std::endl;
if (n < 3) {
foo(n + 1);
}
std::cout << "Thread " << n << " leaving foo." << std::endl;
mtx.unlock();
}
int main() {
std::thread t1(foo, 1);
std::thread t2(foo, 2);
t1.join();
t2.join();
return 0;
}
```
In this example, the function `foo` recursively calls itself twice. Each time it is
called, it acquires the recursive mutex `mtx` and releases it when it returns.
Since the same thread is acquiring the mutex each time, a regular mutex would cause
a deadlock. However, because we're using a `std::recursive_mutex`, the program runs
correctly, and each thread acquires and releases the mutex the correct number of
times.
It's important to note that recursive mutexes come at a cost, as they are generally
slower than regular mutexes due to the additional bookkeeping that is required to
allow for recursive locking. Therefore, they should only be used when necessary.
## My Example
```cpp
#include <iostream>
#include <mutex>
#include <thread>
#include "SimpleTimer.h"
recursive_mutex rm;
mutex m;
int main() {
m.lock();
rm.lock();
rm.lock();
rm.lock();
rm.unlock();
rm.unlock();
rm.unlock();
m.unlock();
return 0;
}
```
```cpp
#include <iostream>
#include <mutex>
#include <thread>
#include "SimpleTimer.h"
recursive_mutex rm;
mutex m;
void Foo(int a) {
rm.lock();
this_thread::sleep_for(chrono::milliseconds(500));
if (a <= 1) {
cout << endl;
rm.unlock();
return;
}
a--;
Foo(a);
rm.unlock();
}
int main() {
t1.join();
t2.join();
return 0;
}
```