如何测试std :: memory_order_relaxed的行为?

eri*_*hsu 5 c++ multithreading stl atomic memory-barriers

我已经阅读了std :: memory_order_relaxed的文档.

放松订购的一部分解释是....

// Thread 1:
r1 = y.load(memory_order_relaxed); // A
x.store(r1, memory_order_relaxed); // B
// Thread 2:
r2 = x.load(memory_order_relaxed); // C 
y.store(42, memory_order_relaxed); // D
Run Code Online (Sandbox Code Playgroud)

并说这个解释......

[它]被允许生产r1 == r2 == 42.特别是,如果由于编译器重新排序或在运行时由D在线程2中的C之前完成,则可能发生这种情况.

我已经理解了解释,并尝试在我的计算机上测试如下代码:

std::atomic<int> x = {0};
std::atomic<int> y = {0};

int r1, r2;

void task1() {
    // Thread 1:
    r1 = y.load(memory_order_relaxed); // A
    x.store(r1, memory_order_relaxed); // B
}

void task2() {
   // Thread 2:
    r2 = x.load(memory_order_relaxed); // C 
    y.store(42, memory_order_relaxed); // D
}


int main()
{
    std::thread t2 (task2);
    std::thread t1 (task1);

    t1.join();
    t2.join();

    cout << "r1: " << r1
        << "\nr2: " << r2 << endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这段代码的结果永远不会 r1 == r2 == 42,据说这是该文档中的一种可能行为.

这段代码有什么问题吗?或者,有任何误解吗?

YSC*_*YSC 8

或者,有任何误解吗?

是的,有一个.是什么std::memory_order_relaxed让你的程序是一个实现(编译器)瞄准的架构,以产生可观察到的副作用的程序r1 == r2 == 42.

实现不必生成这样的程序,并且这样的程序不必产生那种副作用; 无论如何,这可能是一个结果.

如何测试std :: memory_order_relaxed的行为?

我看不出这个问题的一般解决方案.您只能检查您观察到的副作用是否符合规格std::memory_order_relaxed.