【发布时间】:2024-05-02 12:50:02
【问题描述】:
考虑以下伪代码:
expected = null;
if (variable == expected)
{
atomic_compare_exchange_strong(
&variable, expected, desired(), memory_order_acq_rel, memory_order_acq);
}
return variable;
在执行variable == expected 检查时观察没有“获取”语义。
在我看来,desired 总共至少会被调用一次,每个线程最多一次。
此外,如果desired 永远不会返回null,那么这段代码将永远返回null。
现在,我有三个问题:
以上内容一定是真的吗?也就是说,即使每次读取都没有栅栏,我们真的可以对共享变量进行有序的读取吗?
可以在 C++ 中实现吗?如果是这样,怎么做?如果不是,为什么?
(希望有一个理由,而不仅仅是“因为标准是这样说的”。)如果 (2) 的答案是肯定的,那么是否也可以在 C++ 中实现这一点无需 要求
variable == expected执行 原子 读取的variable?
基本上,我的目标是了解是否可以在代码完成后以与非共享变量的性能相同的方式执行共享变量的延迟初始化每个线程至少执行一次?
(这有点像“语言律师”的问题。所以这意味着问题不在于这是一个好主意还是有用的想法,而是关于在技术上是否可以正确地做到这一点。)
【问题讨论】:
-
@nosid:不。见#3。问题还在于是否需要原子性,无论内存排序问题如何。
-
@nosid:我没有提到它,因为我首先提到的是这是伪代码,所以不要指望它是有效的 C++。重点是概念; C++ 只是整个问题的一个方面。
-
那么,如果
variable很大以至于atomic_compare_exchange_strong必须使用互斥锁怎么办?您会尝试在更改对象时访问variable == expected,这意味着例如它的类不变量不必保持。 -
如果没有内存模型来描述多线程读取/写入的工作原理,伪代码几乎没有意义。 C++11 有一个内存模型,但你的伪代码不是 C++,因为 C++ 变量有类型,而这些类型会影响它们在 C++11 内存模型下的行为。
-
@Yakk:我对使用 C++ 内存模型犹豫不决,因为大多数问题都是概念性的,而不是特定于 C++ 的。它只有一部分询问这是否可以在 C++ 中实现,并且对于该部分,您可以为变量提供您认为合适的任何类型以使其工作。你能想象这种在 any(理智的)内存模型上失败并有令人信服的理由(即不仅仅是因为“内存模型这么说”,而是为什么它可能这么说) ?
标签: c++ multithreading c++11 atomic memory-model