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

关于简单生产者/消费者模型中内存序的疑问

C++内存模型:生产者-消费者示例中的重排问题解答

问题1:waitForJob中如何阻止存储操作重排

对应代码:

void waitForJob() {
    assert(!inputValid());
    mWorkerBusy.store(false, std::memory_order_release);
    {
        std::unique_lock lk{mMutex};
        mCV.wait(lk, [&] { return inputValid() || stop(); });
    }
}

有两个关键机制阻止mWorkerBusy.store(false)被重排到mCV.wait()之后:

  • release语义的内存屏障:std::memory_order_release会强制当前线程中,该存储操作之前的所有读写操作,都不能被重排到这个存储之后。也就是说store(false, release)必须在后续的锁构造、wait调用前完成。
  • 互斥锁的内存同步保证:std::unique_lock构造时对mMutex加锁,加锁操作隐含获取语义的内存屏障,会阻止后续wait操作被重排到加锁前的任何操作(包括store(false))。

双重约束下,store(false)一定会在wait执行前完成,不会出现重排导致mWorkerBusy始终为true的情况。

问题2:submitJob中如何阻止notify操作提前执行

对应代码:

template <typename T>
void submitJob(T&& input) {
    assert(ready());
    {
        std::lock_guard lk{mMutex};
        mInput.slot = std::forward<T>(input);
    }
    mWorkerBusy.store(true, std::memory_order_relaxed);
    mCV.notify_one();
}

核心是同一线程内的顺序一致性保证:C++标准明确规定,同一线程中的操作必须按照代码书写顺序呈现给自身。哪怕store用的是memory_order_relaxed(不提供跨线程同步语义),编译器和CPU也不会把后续的notify_one()重排到store(true)之前。

另外,lock_guard销毁时释放互斥锁的操作带有release语义,确保mInput.slot的写入在store(true)前对其他线程可见,但这和store与notify的顺序无关——哪怕没有互斥锁,同一线程里notify也不会跑到store前面。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 17:12:38