Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在多线程单编写器多读取器代码中安全使用int_C++_Concurrency_Stdatomic - Fatal编程技术网

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

C++ 在多线程单编写器多读取器代码中安全使用int,c++,concurrency,stdatomic,C++,Concurrency,Stdatomic,我正在编写一个编写器和多个读取器的并行代码。写入程序将从头到尾填充数组,读取器将按顺序访问数组中的元素。伪代码如下所示: std::vector<Stuff> vec(knownSize); int producerIndex = 0; std::atomic<int> consumerIndex = 0; 消费者线程: for(a while){ vec[producerIndex] = someStuff(); ++producerIndex; } whi

我正在编写一个编写器和多个读取器的并行代码。写入程序将从头到尾填充数组,读取器将按顺序访问数组中的元素。伪代码如下所示:

std::vector<Stuff> vec(knownSize);
int producerIndex = 0;
std::atomic<int> consumerIndex = 0;
消费者线程:

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

我是否需要围绕producerIndex进行任何类型的同步?看起来可能发生的最糟糕的事情是,我会在更新时读取一个旧值,这样我可能会额外旋转一段时间。我遗漏了什么吗?我可以确保对myIndex的每个分配都是唯一的吗?

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

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

这无疑是
producerIndex
上的一场数据竞赛,从一个线程读取,然后在另一个线程中写入。是的,但这似乎是一个“良性竞争”,消费者可以读取旧值或旧值+1,这两者在这里都可以。有可能读取一些从未实际存储在producedIndex中的值吗?@BenJones a race是未定义的行为。它可能是旧值,也可能是新值。但它也可能是wo(新的高位字节和旧的低位字节)的混合体。或者它可能会崩溃,或者产生其他奇怪的东西。我认为你把生产者消费者和作家读者的问题混为一谈了。在第一个线程中,每个生成的项目仅由一个线程使用,而在第二个线程中,多个读卡器可能正在访问同一个元素。每个问题的解决方案都不同。@Christophe这就是我想知道的。Standard说:“如果一个程序的执行包含两个潜在的并发冲突动作,则该程序的执行包含一个数据竞争,其中至少一个动作不是原子的,并且两个动作都不在另一个动作之前发生,但下面描述的信号处理程序的特殊情况除外。任何此类数据竞争都会导致未定义的行为。”所以我想我也需要让生产者索引原子。这不是现代CPU的工作方式(缓存协作,RAM太慢),但是从C++的角度看,你无法区分。