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

C++20 std::latch调试求助:调用taskDone.wait()时程序阻塞

调试C++20 std::latch阻塞问题

你的代码出现阻塞的核心原因是std::jthread的自动join行为导致线程串行执行,形成死锁。

问题分析

在main函数的for循环中,每次创建std::jthread ac{worker_f, i};后,循环迭代结束时ac会被销毁,而std::jthread的析构函数会自动等待线程执行完毕(调用join())。这意味着线程是逐个串行启动并执行完毕的:

  1. 前3个worker线程依次执行,每次将latch计数减1,最终latch变为0。
  2. 当创建第4个worker线程(i=3)时,latch.try_wait()返回true,线程进入分支等待taskDone的信号。但此时main函数被卡在等待这个worker线程完成,而worker线程又在等待main执行taskDone.count_down(),形成死锁,程序彻底阻塞,后续的第5个线程根本没机会启动。

修复方案

将std::jthread存储到容器中,让所有线程可以并发启动,避免main提前等待单个线程结束。修改后的代码如下:

#include <chrono>
#include <iostream>
#include <thread>
#include <latch>
#include <vector>  // 新增头文件

using namespace std::chrono_literals;
std::latch  latch{ 3 };
std::latch taskDone{ 1 };

void worker_f(int this_id)
{
    if (latch.try_wait())
    {
        std::printf("worker %d comes late, full slot ... waiting for the task done\n", this_id);
        taskDone.wait();
        std::printf("task done, worker %d exit\n", this_id);
    }
    else
    {
        std::printf("worker %d comes on time, there is a task for him\n", this_id);
        latch.count_down();
    }
    std::this_thread::sleep_for(100ms);
}
    

int main()
{
    std::vector<std::jthread> workers;  // 用容器存储线程
    workers.reserve(5);  // 预分配空间
    
    for (int i = 0; i < 5; ++i)
    {
        workers.emplace_back(worker_f, i);  // 线程存入容器,不会立即析构join
    }
    
    std::cout << "hello" << std::endl;
    std::printf("waiting for worker\n");
    latch.wait();
    std::printf("full slot, doing task\n");

    taskDone.count_down();
    
    std::printf("task done\n");
    std::this_thread::sleep_for(1000ms);
}

修复后执行流程

  1. 所有5个worker线程同时启动,前3个线程会抢占latch的计数并减到0。
  2. 后2个线程发现latch已计数为0,进入等待taskDone的分支。
  3. main函数在启动所有线程后,等待latch计数归0,随后执行taskDone.count_down()释放等待的线程。
  4. 所有线程最终都能完成执行,输出完整的日志。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 00:50:58