I’ve been reading and learning about the C++ memory model and relaxed atomics and decided to rewrite my Interview question, part 1 using
atomic<bool>’s to synchronize the threads. I took it one step further and created three threads that print A, B, C, A, B, C,…
Each thread waits for its
atomic<bool> to be set to true while spinning; prints then sets the next thread’s flag. The wait is a CAS (compare-and-swap) operation.
Next, I will try to figure out how to relax the
compare_exchange and the
store calls with
memory_order_acquire and
memory_order_release parameters 🙂
Complete listing:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
#include <iostream> #include <atomic> #include <thread> using namespace std; const int COUNT = 3; int main(int argc, char** argv) { atomic<bool> e1{false}, e2{false}, e3{false}; thread t1([&](){ for(int i = 0; i < COUNT; ++i) { bool e = true; while(!e1.compare_exchange_strong(e, false)) e = true; cout << "A" << endl; e2.store(true); } }); thread t2([&](){ for(int i = 0; i < COUNT; ++i) { bool e = true; while(!e2.compare_exchange_strong(e, false)) e = true; cout << "B" << endl; e3.store(true); } }); thread t3([&](){ for(int i = 0; i < COUNT; ++i) { bool e = true; while(!e3.compare_exchange_strong(e, false)) e = true; cout << "C" << endl; e1.store(true); } }); e1.store(true); t1.join(); t2.join(); t3.join(); return 1; } |
A
Program output.
B
C
A
B
C
A
B
C
Program ended with exit code: 1