用std::memory_order_relaxed修改原子变量后,Qt队列连接槽能否看到变更?
Qt队列连接下relaxed原子变量的可见性问题解答
结论:执行槽函数的线程一定能读取到原子变量的新值。
核心原因
Qt的Qt::QueuedConnection内部实现包含了线程间的强同步机制:
- 当发射信号的线程执行
emit variableChanged()时,Qt会将槽函数的调用任务封装后发送到目标线程的事件循环队列,这个过程中会触发等价于C++内存模型中release-acquire的同步屏障。 - 这道屏障会确保:发射线程中
emit之前的所有内存操作(包括用std::memory_order_relaxed完成的原子变量存储),对执行槽函数的线程完全可见。 - 槽函数里用
std::memory_order_relaxed加载原子变量时,由于同步屏障已经保证了内存可见性,所以必然能读到最新的new_value。
补充说明
如果脱离Qt的队列连接,单独使用std::memory_order_relaxed的store和load确实无法跨线程保证可见性,但Qt的队列连接本身提供的跨线程同步语义,已经覆盖了原子变量relaxed语义的局限性。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

