当多个线程并发访问共享全局变量时,线程可能会使用以下命令写入和读取变量不同的副本缓存在不同的处理器核心中。由于不同缓存中存储的值之间可能存在差异,一个线程有可能从其缓存中读取过时的值。
但是,C 11 标准为原子操作提供了 std::atomic 库,确保从其他缓存中读取最新值。这是通过强内存排序实现的,它保证一个线程所做的更改对其他线程以一致的顺序可见。
另一方面, volatile 关键字只是表明变量不应通过以下方式进行优化:编译器,但它不提供任何原子访问保证。它主要是为内存映射 I/O 或信号处理等场景而设计的。
线程间共享变量的上下文中,如下所示:
std::atomicai;
易失性类型和原子类型的行为会有显着差异。易失性不保证原子访问,并且它与 std::atomic 结合使用是多余的。如果硬件平台另有指定,则 volatile 可能对线程之间的原子访问或内存排序没有影响。
另一方面,std::atomic 类型通过各种选项(例如 std::memory_order_seq_cst)提供内存排序,它对所有变量的所有原子操作强制执行单一总顺序。这确保了可见性和排序约束得到维护,并且线程不会以严格定义的顺序观察过时的值。
此外,使用读-修改-写操作,如 Exchange()、compare_exchange_strong() 和 fetch_add () 保证获取最新值。通过在同一线程上下文中执行这些操作,线程将以正确的顺序观察更新的值,从而避免不一致。
使用原子操作需要仔细考虑和理解。建议彻底研究背景材料和现有代码,以在生产代码中有效地实现原子操作。在许多情况下,当不需要原子操作的挑战时,锁可以提供可行的替代方案。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3