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

C++基于std::atomic实现的自定义锁偶发死锁原因排查与修复

自定义同步锁偶发死锁问题分析与修复

死锁根本原因

1. 自定义锁内部逻辑漏洞(核心诱因)

  • get_lock方法时序错误导致丢失唤醒
    原代码中CAS操作失败后,先将expected_tmp重置为目标预期值,再调用wait,存在严重的时序窗口:
    当线程CAS失败、重置expected_tmp之后、调用wait之前,持有锁的线程可能已经完成释放锁操作并发送了notify_all,此时notify信号会被直接丢弃。后续线程进入wait时锁状态刚好等于预期值,会永久阻塞,没有新的notify信号唤醒,直接触发死锁。
  • release_lock释放操作问题
    原代码直接使用=对原子变量赋值,虽然std::atomic的store操作本身是原子的,但未显式控制内存序的场景下,极端情况可能出现指令重排,导致锁释放前的临界区操作未完成就对外暴露了锁可用的状态,用exchange替换直接赋值可以明确保证操作的原子性和内存可见性。

2. 锁作用域设计不合理

原代码将锁对象定义在while循环开头,锁的持有范围覆盖了sleep_for休眠、终止状态检查等非临界区操作,锁持有时间过长,既会导致线程饥饿,也放大了上述逻辑漏洞的触发概率。

修复方案

1. 修正get_lock逻辑顺序

CAS失败后先调用wait等待锁状态变化,唤醒后再重置预期值进入下一轮CAS,避免丢失唤醒:

auto get_lock() -> void{
    bool expected_tmp= expected_input;
    const bool new_object_value = !expected_tmp;

    while (!object.compare_exchange_strong(expected_tmp, new_object_value)) {
        // CAS失败时expected_tmp已经被更新为object当前的实际值,直接传入wait等待状态变化
        object.wait(expected_tmp);
        // 唤醒后再重置预期值,准备下一轮CAS
        expected_tmp= expected_input;
    }

    got_lock = true;
}

2. 优化锁释放逻辑

使用exchange替换直接赋值,保证释放操作的原子性和内存可见性:

auto release_lock() -> void{
    if (!got_lock || already_released) {
        return;
    }
    // 用exchange显式执行原子写,也可指定memory_order_release保证内存序
    object.exchange(expected_input, std::memory_order_release);
    object.notify_all();
    already_released = true;
}

3. 缩小锁作用域

仅在需要同步的临界区代码段内持有锁,非临界区操作(如休眠、终止状态检查)放在锁作用域之外:

while (1) {
    // 仅临界区持有锁
    {
        bool expected_value = false;
        Lock_free_sync lock(flag, expected_value);
        printer(i, " >>> in loop working <<<<<<<<<<<<<<<<<");
        ++count;
        printer(i, " >>> flag is", flag);
    } // 锁在此处自动释放

    this_thread::sleep_for(1s);
    printer(i, " >>> check terminate");

    if (terminate) {
        printer2(i, "stop thread", count);
        return;
    }
    printer(i, "about to reloop");
}

经过以上修改后,代码即可避免偶发死锁问题,并发运行稳定性和效率都会明显提升。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 22:36:03