I was working on one of the examples from the book Concurrency With Modern C++ by Rainer Grimm and I found this code snippet (edited somewhat to get better undestanding of the concept). The code snippet is related to top Release Sequence
#include <atomic>
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
using namespace std::chrono_literals;
int work{0};
std::atomic<int> ready{0};
void consumer() {
while(!(ready.fetch_sub(1, std::memory_order_acquire) > 0)) {
std::this_thread::sleep_for(100ms);
}
work--;
std::cout<<"soemthing is here" << work <<std::endl;
}
void producer() {
work = 2019;
ready.store(2, std::memory_order_release);
}
int main () {
std::thread prod(producer);
std::thread con(consumer);
std::thread con2(consumer);
prod.join();
con.join();
con2.join();
return 0;
}
The output of the above program comes out to be
soemthing is here2018\nsoemthing is here2017\n
soemthing is heresoemthing is here20172017\n\n
soemthing is here2018soemthing is here2017\n\n
soemthing is heresoemthing is here20172017\n\n
Can anyone explain why there is so much difference in the output and how this output can be justified using acquire-release semantics and release sequence.
Note: \n
is used to represent output of std::endl;