C++内存排序一致性
C++ Memory Ordering Consistency
假设我有以下代码:
void* p0 = nullptr;
void* p1 = alloc_some_data();
void f1() {
p0 = p1;
p1 = nullptr;
}
假设f1
在线程 1 上运行。是否有可能(保持代码原样)另一个线程可能会在某个时候将p0
和p1
视为nullptr
(如果编译器或硬件重新排序指令,例如第二个赋值发生在第一个赋值之前)?
问这个问题的原因是因为我想实现一个垃圾收集器,我想知道我是否需要使用原子指令(std::atomic
)从 GC 线程访问指针。如果 GC 线程看到p0 == p1 == alloc_some_data()
则没有问题,但如果 GC 线程看到p0 == p1 == nullptr
就会出现问题,因为这样它会在 p1 中之前的数据报告为无法访问,而这些数据显然是可访问的。
如果你在一个线程中读取一个对象,而另一个线程在没有同步的情况下写入,你就会有数据竞争。这清楚地意味着垃圾回收器需要使用某种同步来读取值。关于你最初的问题:你的代码中没有任何内容表明在写入p1
之前,对p0
的写入变得可见,即另一个线程确实可以将两者都视为空。这与用于与另一个线程通信的同步原语无关:这两个写入之间没有排序。
是的。 虽然不一定可能,但完全有可能,因为这些操作不是原子操作。
(几种可能的情况之一)是这样的:
Thread 2: Get value of p0 (null)
Thread 1: Get value of p1 (non-null)
p0 = p1
p1 = nullptr
Thread 2: Get value of p1 (null)
您需要使用某种形式的访问控制(即互斥锁)。
您的问题的答案是肯定的,但它取决于编译器和 CPU。我认为你还需要使p0
和p1
不稳定。要停止重新排序,您可以使用 _mm_sfence
和 _mm_lfence
intriinsic(适用于 x86/x64)
相关文章:
- 二叉排序树无法编译
- 仅使用绝对值对数组进行排序,并在C++中显示实际值
- C++选择排序算法中的逻辑错误
- 使用C++程序合并排序没有得到正确的输出
- 计算排序向量的向量中唯一值的计数
- 排序算法c++
- 使用2个键的cpp-stl::优先级队列排序不正确
- 将结构向量排序为子组
- 在c++中尝试对对象数组进行排序时,出现std:bad_alloc错误
- 如何对点云数据进行排序
- 对字符串进行排序时,在c++中处理sort()
- 是否有类似std::lower_bound的函数,而不需要排序/分区输入
- 下面是排序算法O(n)吗
- std::sort()函数无法对向量的一部分进行排序
- shell排序中的交换和比较
- clang格式:禁用排序包含
- 显示错误输出的简单数组排序程序
- 为什么我的排序算法会更改数组值
- 试图在c++中对数字列表进行排序
- C++内存排序一致性