[英]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
(对于x86 / x64)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.