4. 互斥量死锁

假设有两个线程 T1 和 T2,它们需要对两个互斥量 mtx1 和 mtx2 进行访问,而且需要按照以下顺序获取互斥量的所有权:

- T1 先获取 mtx1 的所有权,再获取 mtx2 的所有权。

- T2 先获取 mtx2 的所有权,再获取 mtx1 的所有权。

如果两个线程同时执行,就会出现死锁问题。因为 T1 获取了 mtx1 的所有权,但是无法获取 mtx2 的所有权,而 T2 获取了 mtx2 的所有权,但是无法获取 mtx1 的所有权,两个线程互相等待对方释放互斥量,导致死锁。

为了解决这个问题,可以让两个线程按照相同的顺序获取互斥量的所有权。例如,都先获取 mtx1 的所有权,再获取 mtx2 的所有权,或者都先获取 mtx2 的所有权,再获取 mtx1 的所有权。这样就可以避免死锁问题。

以下是按照第二种方案修改后的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx1, mtx2;

void func1()
{
mtx2.lock();
std::cout << "Thread 1 locked mutex 2" << std::endl;
mtx1.lock();
std::cout << "Thread 1 locked mutex 1" << std::endl;
mtx1.unlock();
std::cout << "Thread 1 unlocked mutex 1" << std::endl;
mtx2.unlock();
std::cout << "Thread 1 unlocked mutex 2" << std::endl;
}

void func2()
{
mtx2.lock();
std::cout << "Thread 2 locked mutex 2" << std::endl;
mtx1.lock();
std::cout << "Thread 2 locked mutex 1" << std::endl;
mtx1.unlock();
std::cout << "Thread 2 unlocked mutex 1" << std::endl;
mtx2.unlock();
std::cout << "Thread 2 unlocked mutex 2" << std::endl;
}

int main()
{
std::thread t1(func1);
std::thread t2(func2);
t1.join();
t2.join();
return 0;
}

在上面的代码中,T1 先获取 mtx2 的所有权,再获取 mtx1 的所有权,而 T2 也是先获取 mtx2 的所有权,再获取 mtx1 的所有权,这样就避免了死锁问题。


4. 互斥量死锁
http://binbo-zappy.github.io/2024/11/27/cpp-多线程/4-互斥量死锁/
作者
Binbo
发布于
2024年11月27日
许可协议