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

如何等待另一个线程完成下一次循环迭代?

实现方案

核心实现代码

首先补充全局同步变量,然后实现目标函数:

#include <atomic>
#include <chrono>
#include <thread>
#include <condition_variable>
#include <mutex>

// 新增同步变量
std::condition_variable cv;
std::mutex cv_mutex;
std::atomic<unsigned long> iteration_count = 0;

void notify_any_waiting_threads()
{
    // 递增迭代计数器,确保内存可见性
    iteration_count.fetch_add(1, std::memory_order_release);
    // 通知所有等待的线程
    cv.notify_all();
}

void wait_for_worker_thread_iteration()
{
    std::unique_lock<std::mutex> lock(cv_mutex);
    // 记录当前迭代次数
    const auto target_iteration = iteration_count.load(std::memory_order_acquire);
    // 等待直到迭代次数发生变化(避免虚假唤醒)
    cv.wait(lock, [target_iteration] {
        return iteration_count.load(std::memory_order_acquire) != target_iteration;
    });
}

// 原有代码保持不变
void do_work()
{
    std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟耗时工作
}

std::atomic_bool kill_worker_thread = false;
std::atomic_bool worker_should_be_idle = false;
void worker_thread_function()
{
    while (!kill_worker_thread) {

        if (worker_should_be_idle) {
            std::this_thread::sleep_for(std::chrono::seconds(1)); // 空闲时休眠避免空转
        } else {
            do_work();
        }

        notify_any_waiting_threads();
    }
}

void observer_thread_function()
{
    worker_should_be_idle = true;
    wait_for_worker_thread_iteration();
    // 此时可确保worker线程后续迭代都会进入idle状态,不再执行do_work()
}

int main()
{
    std::thread worker_thread(worker_thread_function);

    std::this_thread::sleep_for(std::chrono::milliseconds(1800)); // 模拟观察者线程延迟启动
    std::thread observer_thread_1(observer_thread_function);

    // 清理逻辑
    observer_thread_1.join();
    kill_worker_thread = true;
    worker_thread.join();
}

关键细节说明

  • 条件变量的合理性:每次迭代完成后调用notify_all()完全合法,这正是条件变量的核心用途——在状态变化时唤醒等待线程,这里的“迭代完成”就是明确的触发点。
  • 谓词的作用:wait()的谓词用于规避虚假唤醒,即使线程被唤醒,也要确认迭代次数确实更新,才会退出等待逻辑。
  • 内存序优化:memory_order_release和memory_order_acquire确保worker线程对iteration_count的修改能被等待线程立即感知,避免内存可见性问题。

替代同步原语分析

  • std::latch/std::barrier:这类原语适用于一次性或固定次数的同步场景,但你的需求是支持多次等待“下一次迭代”,条件变量的灵活性更匹配。
  • std::atomic_flag:仅能实现简单信号量功能,无法跟踪迭代次数,无法区分“是否为目标迭代”,可靠性和直观性不如条件变量。

关于“等待下一次迭代”是否为反模式

这不是反模式,而是非常常见的线程同步需求:

  • 典型场景包括:等待工作线程完成单次任务后读取结果、同步线程间状态切换(如你的场景中确认worker进入idle状态)、批量任务的进度同步等。
  • 只要同步逻辑清晰、避免死锁和竞态,这种设计完全合理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 10:44:55