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();
}

在上面的代码中,我们保证了两个线程始终按照相同的顺序获取锁,从而避免了交叉持有锁的情况。

C++ 死锁:两个锁交叉的风险与解决方案

原文地址: https://www.cveoy.top/t/topic/kWes 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录