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

如何用C++ std::thread实现线程全完成Part1后再执行Part2?

多线程同步:所有线程完成Part1后再执行Part2

问题分析

你需要实现的是**线程屏障(Barrier)**机制:让所有线程在执行Part2前,必须等待其他线程全部完成Part1。你之前用mutex+原子变量的方案逻辑存在缺陷——仅让最后一个线程执行unlock,但其他线程已经调用lock且没有唤醒逻辑,导致它们一直阻塞无法继续。

可行解决方案

方案1:使用C++20的std::barrier(推荐)

C++20引入的std::barrier专门处理这类“所有线程到达同步点后再统一继续”的场景,用法简洁高效:

首先在类中定义共享的barrier对象:

#include <barrier>

class TMainForm {
private:
    std::barrier<>* threadBarrier = nullptr;
public:
    void foo(int numThreads);
    void StartingThreads();
};

修改函数实现:

void TMainForm::foo(int numThreads)
{
    std::cout << "Part 1: do some work" << std::endl;

    // 等待所有线程完成Part1
    threadBarrier->arrive_and_wait();

    std::cout << "Part 2: do some work" << std::endl;
}

void TMainForm::StartingThreads()
{
    int threads = std::thread::hardware_concurrency();
    // 初始化barrier,指定需要等待的线程总数
    threadBarrier = new std::barrier<>(threads);

    std::vector<std::thread> t(threads);
    for (int i = 0; i < threads; i++)
        t[i] = std::thread(&TMainForm::foo, this, threads);

    for (auto& th : t)
        th.join();

    delete threadBarrier;
    threadBarrier = nullptr;
}

方案2:使用std::condition_variable + std::mutex + 原子变量(兼容C++11/17)

如果你的环境不支持C++20,可以用条件变量手动实现屏障逻辑:

在类中添加共享同步变量:

#include <condition_variable>
#include <atomic>

class TMainForm {
private:
    std::mutex mtx;
    std::condition_variable cv;
    std::atomic<int> completedPart1 = 0;
    int totalThreads = 0;
public:
    void foo();
    void StartingThreads();
};

修改函数实现:

void TMainForm::foo()
{
    std::cout << "Part 1: do some work" << std::endl;

    // 原子递增完成Part1的线程数
    int current = completedPart1.fetch_add(1) + 1;

    std::unique_lock<std::mutex> lock(mtx);
    // 非最后完成的线程,等待通知
    if (current < totalThreads) {
        cv.wait(lock, [this](){ return completedPart1 == totalThreads; });
    } else {
        // 最后一个线程完成,唤醒所有等待的线程
        cv.notify_all();
    }

    std::cout << "Part 2: do some work" << std::endl;
}

void TMainForm::StartingThreads()
{
    totalThreads = std::thread::hardware_concurrency();
    completedPart1 = 0; // 重置计数器

    std::vector<std::thread> t(totalThreads);
    for (int i = 0; i < totalThreads; i++)
        t[i] = std::thread(&TMainForm::foo, this);

    for (auto& th : t)
        th.join();
}

原方案失败原因

你之前的逻辑是让未完成全部Part1的线程调用mutex::lock,但缺少唤醒机制:一旦某个线程成功lock,其他线程会持续卡在lock调用处;即使最后一个线程执行unlock,也只有一个线程能继续,剩余线程仍会阻塞。正确的做法是用条件变量等待,当所有线程完成Part1后统一唤醒,而非用mutex的lock/unlock控制执行流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 11:10:26