Memory Acquisition / Release

In the example:

#include <thread>
#include <atomic>
#include <cassert>
#include <vector>

std::vector<int> data;
std::atomic<int> flag = ATOMIC_VAR_INIT(0);

void thread_1()
{
    data.push_back(42);
    flag.store(1, std::memory_order_release);
}

void thread_2()
{
    int expected=1;
    while (!flag.compare_exchange_strong(expected, 2, std::memory_order_acq_rel)) {
        expected = 1;
    }
}

void thread_3()
{
    while (flag.load(std::memory_order_acquire) < 2)
        ;
    assert(data.at(0) == 42); // will never fire
}

int main()
{
    std::thread a(thread_1);
    std::thread b(thread_2);
    std::thread c(thread_3);
    a.join(); b.join(); c.join();
}

1- If I replace std :: memory_order_acq_rel in thread_2 with std :: memory_order_acquire, can I guarantee that the statement in thread_3 will never fire?

2 - Can std :: memory_order_release synchronize with 2 threads using std :: memory_order_acquire (if 2 threads look at the same flag with receive semantics)?

+4
source share
1 answer
  • You have nothing to synchronize with stream 2, so std :: memory_order_relaxed memory ordering is more rational.

  • std:: memory_order_release x std:: memory_order_acquire x -- x

0

All Articles