在多线程单写入器多读取器代码中安全使用int

时间:2017-03-21 22:06:48

标签: c++ concurrency stdatomic

我正在编写具有单个编写器和多个读取器的并行代码。编写器将从头到尾填充数组,读者将按顺序访问数组的元素。伪代码类似于以下内容:

for(a while){
  vec[producerIndex] = someStuff();
  ++producerIndex;
}

制作人主题:

while(!finished){
   int myIndex = consumerIndex++;
   while(myIndex >= producerIndex){ spin(); }
   use(vec[myIndex]);
}

消费者主题:

{{1}}

我是否需要围绕producerIndex进行任何类型的同步?似乎可能发生的最糟糕的事情是,我会在更新时读取旧值,这样我可能会花费额外的时间。我错过了什么吗?我可以确定myIndex的每个作业都是唯一的吗?

2 个答案:

答案 0 :(得分:4)

正如评论所指出的,这段代码有一个数据竞争。不要猜测代码是否有机会做你想做的事情,而是修复它:将producerIndexconsumerIndex的类型从int更改为std::atomic<int>并让编译器实现者和标准库实现者担心如何在目标平台上正常工作。

答案 1 :(得分:0)

阵列可能会存储在缓存中,因此所有线程都有自己的副本。每当生产者在数组中放入一个新值时,这将在存储地址上设置脏位,因此使用该值的每个其他线程都会将其从RAM中检索到缓存中自己的副本。 这意味着您将获得大量缓存未命中但没有竞争条件。 :)