假设我有以下代码:
void* p0 = nullptr;
void* p1 = alloc_some_data();
void f1() {
p0 = p1;
p1 = nullptr;
}
假设 f1
在线程 1 上运行。是否有可能(保持代码不变)另一个线程可能在某个时候看到 p0
和 p1
as nullptr
(如果编译器或硬件重新排序指令,例如第二个赋值发生在第一个之前)?
我问这个的原因是因为我想实现一个垃圾收集器并且我想知道我是否需要使用原子指令 (std::atomic
) 从 GC 线程访问指针.如果 GC 线程看到 p0 == p1 == alloc_some_data()
就没有问题,但是如果 GC 线程看到 p0 == p1 == nullptr
就会有问题,因为那时当它显然可以访问时,它将报告先前在 p1 中的数据无法访问。
最佳答案
如果您在一个线程中读取一个对象,而该对象是由另一个线程在没有同步的情况下写入的,那么您就会发生数据竞争。这清楚地暗示您的垃圾收集器将需要使用某种同步来读取这些值。关于您最初的问题:您的代码中没有任何内容表明对 p0
的写入在写入 p1
之前变得可见,即,另一个线程确实可以,看到两者都为空。这独立于用于与另一个线程通信的同步原语:这两个写入之间没有顺序。
关于C++ 内存顺序一致性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12451850/