【问题标题】:Do I need to guard a variable that is written by one thread and read by many?我是否需要保护一个由一个线程写入并由多个线程读取的变量?
【发布时间】:2016-04-13 16:07:08
【问题描述】:

我正在编写一个数据采集系统。该系统既可以处理来自我们的信号数字化仪的快速数据,又可以对探测器的高压系统等进行缓慢的控制/监控。慢速控制系统每秒读取一次电压并将其写入数据结构。

在写入磁盘之前,每个事件都标有其检测器的电压。为此,事件处理线程读取由慢速控制/监视线程编写的结构。

鉴于在读取电压后 X 微秒内发生的事件是否被标记为前一秒的电压读取并不重要:我是否需要使用互斥锁来保护数据结构或原子变量结构?

【问题讨论】:

  • 据我所知应该没有问题。
  • 是否可以读取和写入同一个对象?

标签: c++ multithreading mutex atomic


【解决方案1】:

如果我理解正确,每秒一个线程正在读取电压,将其写入某个“数据结构”,而其他线程不时从该数据结构中读取(我说的对吗?)

如果此“数据结构”具有原子加载和存储(例如 x86 上的intchar 等),那么其他线程正在读取的值可能永远不会改变(或其他可能会发生令人讨厌的事情,例如重新排序)。您需要同步以确保从其内存存储而不是从缓存存储正确读取/写入原子存储/加载。

如果这个“数据结构”不是原子的 - 那么我们正在处理未定义的行为,这总是错误的。

所以你确实需要使“数据结构”既是原子的又是同步的,要么通过原子,要么通过锁。

如果这个“数据结构”足够小,std::atomic 似乎适合这里。如果没有,请查看您的系统是否支持读写锁,它们似乎非常适合这里。

【讨论】:

  • "volatile" 将阻止缓存原子变量
  • 是的,不过他似乎并不在意这些。
  • @Eugene volatile 不能用于同步。
【解决方案2】:

是的,您需要数据是原子的,以消除数据竞争的可能性。在极端性能要求的情况下,您可以在读取或写入变量时使用宽松的内存排序 - 这将确保原子性,但不会添加排序(如果架构不是自然排序的,如 Intel)

【讨论】: