简体   繁体   English

共享变量的竞争条件

[英]Race condition for shared variable

I have a shared variable of type double . 我有一个double类型的共享变量。 This variable will be accessed by two threads. 这个变量将由两个线程访问。 One thread will ever only write the variable, whereas the other thread will ever only read the variable. 一个线程将只编写变量,而另一个线程将只读取变量。

Do I still get race condition here? 我还能在这里得到比赛条件吗? If yes, is there an "easy" way in C++ to implement atomic access? 如果是的话,C ++中是否有一种“简单”的方式来实现原子访问? How do I implement it efficiently if there is going to be much much more reads than writes? 如果有更多的读取而不是写入,我如何有效地实现它? Do I need to mark the variable as volatile ? 我需要将变量标记为volatile吗?

EDIT: OK the "reader" thread works periodically on batches of data and the propagation of the new value is not time-sensitive. 编辑:好的“阅读器”线程定期对批量数据工作,新值的传播不是时间敏感的。 Instead of implementing complicated interlocking that I have no good way to test, I can just declare another temp variable the writer thread will write to. 我没有实现我没有好的测试方法的复杂联锁,而是可以声明写入线程将写入的另一个临时变量。 Then when the reader is finished with one batch, it can atomically propagate the temp value to the actual variable. 然后,当读者完成一个批处理时,它可以将临时值原子传播到实际变量。 Would that be race-condition-free? 这会没有竞争条件吗?

Yes, there's a race condition, since double variables are not atomic on most processors. 是的,存在竞争条件,因为在大多数处理器上double变量不是原子的。

Use 3 doubles (possibly an array with extra padding in between, to avoid false sharing that kills performance). 使用3个双打(可能是一个阵列之间有额外的填充,以避免错误共享,从而导致性能下降)。

One is owned by the reader, one is owned by the writer, one is being handed off. 一个由读者拥有,一个由作者拥有,一个正在交付。

To write: write to the write slot, then atomically swap (eg with InterlockedExchange ) the pointer/index for the write slot with the index for the handoff slot. 写入:写入写入时隙,然后原子地交换(例如,使用InterlockedExchange )写入时隙的指针/索引和切换时隙的索引。 Since the index is pointer-sized or smaller, atomically swapping is easy as long as the variable is properly aligned. 由于索引是指针大小或更小,只要变量正确对齐,原子交换就很容易。 If by chance your platform offers interlocked-exchange with and without memory barriers, use the one with. 如果您的平台偶然提供带或不带内存屏障的互锁交换,请使用带有内存屏障的平台。

To read: atomically swap the pointer/index for the read slot with the index for the handoff variable. 要读取:原子地将读取槽的指针/索引与切换变量的索引交换。 Then read the read slot. 然后读取读取插槽。

You should actually include a version number also, since the read thread will tend to bounce between the latest and previous slot. 您实际上也应该包含版本号,因为读取的线程将倾向于在最新和上一个插槽之间反弹。 When reading, read both before and after the swap, then use the one with the later version. 阅读时,请在交换之前和之后阅读,然后使用更高版本的版本。

Or, in C++11, just use std::atomic . 或者,在C ++ 11中,只需使用std::atomic

Warning: the above only works for single writer/single reader (the particular case in this question). 警告:以上内容仅适用于单个编写器/单个阅读器(此问题中的特定情况)。 If you have multiple, think about a reader-writer lock or similar protecting all access to the variable. 如果您有多个,请考虑读取器 - 写入器锁或类似的保护对变量的所有访问。

You might want to take a look at this that discusses reads/writes of primitive types: 您可能想看一下讨论基本类型的读/写:

Are C++ Reads and Writes of an int Atomic? C ++是否读取和写入了原子?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM