One Time Synchronization of Threads
Explore one-time synchronization of threads with examples.
We'll cover the following...
Sender-receiver workflows are quite common for threads. In such a workflow, the receiver is waiting for the sender’s notification before Future continues to work. There are various ways to implement these workflows. With C++11, you can use condition variables or promise/future pairs; with C++20, you can use std::atomic_flag
. Each way has its pros and cons. Consequently, I want to compare them. I assume you don’t know the details of condition variables or promises and futures. Therefore, I provide a short refresher.
Condition variables
A condition variable can fulfill the role of a sender or a receiver. As a sender, it can notify one or more receivers.
Run the following program 4 times and notice the output.
#include <iostream>#include <condition_variable>#include <mutex>#include <thread>#include <vector>std::mutex mut;std::condition_variable condVar;std::vector<int>myVec{};void prepareWork() {{std::lock_guard<std::mutex> lck(mut);myVec.insert(myVec.end(), {0, 1, 0, 3});}std::cout << "Sender: Data prepared." << '\n';condVar.notify_one();}void completeWork() {std::cout << "Waiter: Waiting for data." << '\n';std::unique_lock<std::mutex> lck(mut);condVar.wait(lck, []{ return not myVec.empty(); });myVec[2] = 2;std::cout << "Waiter: Complete the work." << '\n';for (auto i: myVec) std::cout << i << " ";std::cout << '\n';}int main() {std::cout << '\n';std::thread t1(prepareWork);std::thread t2(completeWork);t1.join();t2.join();std::cout << '\n';}
The program has two child threads: t1
...