为什么这可能导致僵局?

朱恩·基恩

请参阅以下从http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4507.pdf第12页提供的代码

using namespace std::experimental::parallel;
std::atomic<int> x = 0;
int a[] = {1,2};
for_each(par, std::begin(a), std::end(a), [&](int n) {
  x.fetch_add(1, std::memory_order_relaxed);
  // spin wait for another iteration to change the value of x
  while (x.load(std::memory_order_relaxed) == 1) { }
});

在此示例中附有注释:

上面的示例取决于迭代的执行顺序,因此未定义(可能会死锁)。

但是我不明白为什么会导致僵局。据我了解,尽管将内存顺序指定为std::memory_order_relaxed,但这仅与某个线程看到另一个线程所做的某些更改的时间有关,因此最终(在可能无限制的时间之后)该更改应该始终由读取线程注意到。

有人可以解释吗?谢谢!

温西

示例代码可能死锁的原因与的使用无关memory_order_relaxed

原子变量的更改将对另一个内核可见,如果不可见(根据标准,它应该变为可见),则它与内存排序无关,后者仅用于指定相对于其他内存操作的排序方式原子操作。

链接引用的文档中给出的示例可能会死锁,因为显然不能保证执行是真正并发的。在更高的草案(N4640)中,该文本进行了修订:

...取决于迭代的执行顺序,并且如果两个迭代均在同一执行线程上依次执行,则不会终止。

这就是全部内容。如果两个迭代都按顺序执行,则第一个迭代将继续旋转一个永不改变的值。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章