The code below is a sender/receiver setup in C++ where the sender is in one thread, the receiver is in another, and the data being sent/received is "shared" (global). The code uses the <thread>
header, std::unique_lock
, and std::condition_variable
.
I would love a critique on everything below ConditionVariable.notify_one();
in the Receiver
function and everything below ConditionVariable.notify_one();
in the Sender
function.
Regarding those final line(s) of Receiver
and Sender
: I'm having some doubts around the effects of blocking that happens upon lock and wait. Also, at the bottom of each of the two functions, I'm not entirely sure about the need for lock... since, as soon as the loop iteration ends, the destructor of unique_lock will immediately do an unlock.
#include <mutex>
#include <thread>
#include <string>
// Declaration-only for brevity. Assume this returns the data that `Sender` will send.
std::string GenerateMyString();
// Global variables for threads (we'll have two threads, one for `Sender` and
// one for `Receiver`
std::mutex Mutex;
std::string DataGeneratedWithinSender;
bool Free = false;
std::condition_variable ConditionVariable;
// `Sender` and `Receiver` functions will each run in their own thread.
void Sender() {
for (int i = 0; i < 5; ++i) {
std::unique_lock<std::mutex> unq_lck{Mutex};
DataGeneratedWithinSender = GenerateMyString();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
Free = true;
unq_lck.unlock();
ConditionVariable.notify_one();
unq_lck.lock();
ConditionVariable.wait(unq_lck, []() { return !Free; });
}
}
void Receiver() {
std::string data;
for (int i = 0; i < 5; ++i) {
std::unique_lock<std::mutex> unq_lck{Mutex};
ConditionVariable.wait(unq_lck, []() { return Free; });
data = DataGeneratedWithinSender;
Free = false;
unq_lck.unlock();
ConditionVariable.notify_one();
// *** DO SOMETHING WITH `data` HERE ***
// This `Receiver` function is now ready for the next piece of data to be sent to it.
unq_lck.lock();
}
}
int main() {
std::thread t_1(Receiver);
std::thread t_2(Sender);
t_1.join();
t_2.join();
return 0;
}