...
/Acquire Release: The Typical Misunderstanding
Acquire Release: The Typical Misunderstanding
This lesson highlights a typical misunderstanding while using acquire-release in C++.
We'll cover the following...
What is my motivation for writing about the typical misunderstanding of the acquire-release semantic? Many of my readers and students have already fallen into this trap. Let’s look at the straightforward case. Here is a simple program as a starting point.
Press + to interact
// acquireReleaseWithWaiting.cpp#include <atomic>#include <iostream>#include <thread>#include <vector>std::vector<int> mySharedWork;std::atomic<bool> dataProduced(false);void dataProducer(){mySharedWork = {1, 0, 3};dataProduced.store(true, std::memory_order_release);}void dataConsumer(){while( !dataProduced.load(std::memory_order_acquire) );mySharedWork[1] = 2;}int main(){std::cout << std::endl;std::thread t1(dataConsumer);std::thread t2(dataProducer);t1.join();t2.join();for (auto v: mySharedWork){std::cout << v << " ";}std::cout << "\n\n";}
The consumer thread t1
in line 17 waits until the consumer thread t2
in line 13 sets dataProduced
to true
. dataProduced
is the guard and it guarantees that access to the non-atomic variable mySharedWork
is synchronized. This means that the producer thread t2
initializes mySharedWork
, then the consumer thread t1
finishes the work by setting mySharedWork[1]
...