[英]Why does code mutating a shared variable across threads apparently NOT suffer from a race condition?
[英]Race condition for shared variable
我有一个double
类型的共享变量。 这个变量将由两个线程访问。 一个线程将只编写变量,而另一个线程将只读取变量。
我还能在这里得到比赛条件吗? 如果是的话,C ++中是否有一种“简单”的方式来实现原子访问? 如果有更多的读取而不是写入,我如何有效地实现它? 我需要将变量标记为volatile
吗?
编辑:好的“阅读器”线程定期对批量数据工作,新值的传播不是时间敏感的。 我没有实现我没有好的测试方法的复杂联锁,而是可以声明写入线程将写入的另一个临时变量。 然后,当读者完成一个批处理时,它可以将临时值原子传播到实际变量。 这会没有竞争条件吗?
是的,存在竞争条件,因为在大多数处理器上double
变量不是原子的。
使用3个双打(可能是一个阵列之间有额外的填充,以避免错误共享,从而导致性能下降)。
一个由读者拥有,一个由作者拥有,一个正在交付。
写入:写入写入时隙,然后原子地交换(例如,使用InterlockedExchange
)写入时隙的指针/索引和切换时隙的索引。 由于索引是指针大小或更小,只要变量正确对齐,原子交换就很容易。 如果您的平台偶然提供带或不带内存屏障的互锁交换,请使用带有内存屏障的平台。
要读取:原子地将读取槽的指针/索引与切换变量的索引交换。 然后读取读取插槽。
您实际上也应该包含版本号,因为读取的线程将倾向于在最新和上一个插槽之间反弹。 阅读时,请在交换之前和之后阅读,然后使用更高版本的版本。
或者,在C ++ 11中,只需使用std::atomic
。
警告:以上内容仅适用于单个编写器/单个阅读器(此问题中的特定情况)。 如果您有多个,请考虑读取器 - 写入器锁或类似的保护对变量的所有访问。
您可能想看一下讨论基本类型的读/写:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.