You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何递归锁定std::mutex未触发死锁?代码解析

为啥你的代码没触发死锁?

首先,你根本没用到多线程

死锁的本质是多个线程互相攥着对方需要的锁,谁也不肯放,形成循环等待。但你的代码从头到尾只有主线程在跑,所有函数调用都是单线程内的顺序执行,连第二个线程都没有,完全不满足死锁的前提。

其次,单线程重复加锁不是死锁

就算你加了多线程,当前代码里的逻辑是同一个线程两次抢同一个std::mutex——process先拿锁,然后调用print再抢同一把锁。这里要注意:std::mutex是非递归锁,同一个线程重复抢自己已经持有的非递归锁属于未定义行为(可能卡主、崩溃,但这不是死锁)。死锁特指不同线程之间的互相等待,跟单线程内的重复加锁不是一回事。

真要构造死锁,得这么写

要触发死锁,必须凑齐四个条件:互斥、持有并等待、不可剥夺、循环等待。比如搞两个线程,一个先拿锁A再抢锁B,另一个先拿锁B再抢锁A:

#include <iostream>
#include <mutex>
#include <thread>
#include <chrono>

std::mutex mutexA;
std::mutex mutexB;

void thread1() {
    std::lock_guard<std::mutex> lockA(mutexA);
    // 睡一会儿,确保thread2能先拿到mutexB
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    std::lock_guard<std::mutex> lockB(mutexB);
    std::cout << "Thread1执行完毕" << std::endl;
}

void thread2() {
    std::lock_guard<std::mutex> lockB(mutexB);
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    std::lock_guard<std::mutex> lockA(mutexA);
    std::cout << "Thread2执行完毕" << std::endl;
}

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

这段代码里,thread1攥着mutexA等mutexB,thread2攥着mutexB等mutexA,谁也动不了,这才是真正的死锁。


内容的提问来源于stack exchange,提问作者twn29004

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 15:30:15