C++ 死锁:两个锁交叉的风险与解决方案
C++ 中两个锁交叉指的是两个线程在执行时,每个线程都持有一个锁,但是在某个时刻,线程 1 需要获取线程 2 持有的锁,而线程 2 也需要获取线程 1 持有的锁,导致两个线程互相等待对方释放锁,从而形成了死锁。
以下是一个简单的示例代码,演示了两个线程交叉持有锁导致死锁的情况:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mutex1, mutex2;
void thread1() {
std::cout << "Thread 1 started." << std::endl;
mutex1.lock();
std::cout << "Thread 1 acquired mutex1." << std::endl;
// 休眠 1 秒钟,模拟一些耗时操作
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Thread 1 trying to acquire mutex2." << std::endl;
mutex2.lock();
std::cout << "Thread 1 acquired mutex2." << std::endl;
mutex2.unlock();
mutex1.unlock();
}
void thread2() {
std::cout << "Thread 2 started." << std::endl;
mutex2.lock();
std::cout << "Thread 2 acquired mutex2." << std::endl;
// 休眠 1 秒钟,模拟一些耗时操作
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Thread 2 trying to acquire mutex1." << std::endl;
mutex1.lock();
std::cout << "Thread 2 acquired mutex1." << std::endl;
mutex1.unlock();
mutex2.unlock();
}
int main() {
std::thread t1(thread1);
std::thread t2(thread2);
t1.join();
t2.join();
return 0;
}
在上面的代码中,两个线程分别持有 mutex1 和 mutex2,但是在执行过程中,线程 1 需要获取 mutex2,而线程 2 需要获取 mutex1,导致两个线程互相等待对方释放锁,从而形成了死锁。
为了避免这种情况的发生,我们需要保证在获取锁的时候,始终按照相同的顺序获取锁,从而避免出现交叉持有锁的情况。例如,我们可以将上面的代码改为以下形式:
void thread1() {
std::cout << "Thread 1 started." << std::endl;
mutex1.lock();
std::cout << "Thread 1 acquired mutex1." << std::endl;
// 休眠 1 秒钟,模拟一些耗时操作
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Thread 1 trying to acquire mutex2." << std::endl;
mutex2.lock();
std::cout << "Thread 1 acquired mutex2." << std::endl;
mutex2.unlock();
mutex1.unlock();
}
void thread2() {
std::cout << "Thread 2 started." << std::endl;
mutex1.lock();
std::cout << "Thread 2 acquired mutex1." << std::endl;
// 休眠 1 秒钟,模拟一些耗时操作
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Thread 2 trying to acquire mutex2." << std::endl;
mutex2.lock();
std::cout << "Thread 2 acquired mutex2." << std::endl;
mutex2.unlock();
mutex1.unlock();
}
在上面的代码中,我们保证了两个线程始终按照相同的顺序获取锁,从而避免了交叉持有锁的情况。
原文地址: https://www.cveoy.top/t/topic/kWes 著作权归作者所有。请勿转载和采集!