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

如何用条件变量修复线程交替打印中的死锁问题?

解决多线程循环打印a/b/c的死锁问题

问题根源

原代码存在两个核心问题导致偶尔无输出或死锁:

  • 通知丢失:主线程启动线程后立刻调用var_a.notify_one(),此时线程A可能还未完成初始化进入等待状态,通知直接被丢弃,所有线程卡在wait无法继续。
  • 虚假唤醒:std::condition_variable::wait可能发生系统层面的虚假唤醒,没有谓词校验的话,线程会错误执行,破坏打印顺序甚至引发死锁。

修复后的代码

#include <iostream>
#include <mutex>
#include <condition_variable>
#include <thread>

// 共享状态:标记当前允许打印的字符
char current_char = 'a';

void print(
    std::mutex& mutex, 
    std::condition_variable& cv, 
    int count,
    char target_ch,
    char next_ch)
{
    std::unique_lock<std::mutex> lock(mutex);
    for (int i = 0; i < count; ++i)
    {
        // 等待直到轮到当前线程打印(带谓词避免虚假唤醒)
        cv.wait(lock, [target_ch](){ return current_char == target_ch; });
        std::cout << target_ch;
        // 更新状态为下一个要打印的字符
        current_char = next_ch;
        // 通知所有线程检查状态
        cv.notify_all();
    }
};

int main()
{
    const int count = 10;

    std::condition_variable cv;
    std::mutex mutex;

    auto thread_a = std::thread(&print, std::ref(mutex), std::ref(cv), count, 'a', 'b');
    auto thread_b = std::thread(&print, std::ref(mutex), std::ref(cv), count, 'b', 'c');
    auto thread_c = std::thread(&print, std::ref(mutex), std::ref(cv), count, 'c', 'a');

    thread_a.join();
    thread_b.join();
    thread_c.join();

    std::cout << std::endl;
    return 0;
}

关键优化点

  • 用**共享变量current_char**统一控制打印顺序,每个线程通过wait的谓词判断是否轮到自己,彻底解决通知丢失和虚假唤醒问题。
  • 所有线程共用一个condition_variable,每次打印后更新状态并通知所有线程,线程自行校验状态,简化了多条件变量的复杂依赖。
  • 逻辑更清晰,避免了原代码中线程启动顺序与通知时机不匹配的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 12:16:11