How do memory_order_seq_cst and memory_order_acq_rel differ?

前端 未结 4 1221
夕颜
夕颜 2020-12-02 14:02

Stores are release operations and loads are acquire operations for both. I know that memory_order_seq_cst is meant to impose an additional total ordering for al

4条回答
  •  一向
    一向 (楼主)
    2020-12-02 14:51

    Still use the definition and example from memory_order. But replace memory_order_seq_cst with memory_order_release in store and memory_order_acquire in load.

    Release-Acquire ordering guarantees everything that happened-before a store in one thread becomes a visible side effect in the thread that did a load. But in our example, nothing happens before store in both thread0 and thread1.

    x.store(true, std::memory_order_release); // thread0
    
    y.store(true, std::memory_order_release); // thread1
    

    Further more, without memory_order_seq_cst, the sequential ordering of thread2 and thread3 are not guaranteed. You can imagine they becomes:

    if (y.load(std::memory_order_acquire)) { ++z; } // thread2, load y first
    while (!x.load(std::memory_order_acquire)); // and then, load x
    
    if (x.load(std::memory_order_acquire)) { ++z; } // thread3, load x first
    while (!y.load(std::memory_order_acquire)); // and then, load y
    

    So, if thread2 and thread3 are executed before thread0 and thread1, that means both x and y stay false, thus, ++z is never touched, z stay 0 and the assert fires.

    However, if memory_order_seq_cst enters the picture, it establishes a single total modification order of all atomic operations that are so tagged. Thus, in thread2, x.load then y.load; in thread3, y.load then x.load are sure things.

提交回复
热议问题