Last active
June 10, 2018 15:25
-
-
Save fxfactorial/ada1ed6377b1f014811233b5ac368028 to your computer and use it in GitHub Desktop.
Producer and Consumer threads using Condition variable and mutex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Compile With: $ clang++ -ggdb -std=c++17 -fsanitize=address src/main.cpp -o T | |
#include <condition_variable> | |
#include <iostream> | |
#include <mutex> | |
#include <queue> | |
#include <sstream> | |
#include <thread> | |
int main() { | |
auto do_wait = [](int s) { | |
using namespace std::chrono; | |
this_thread::sleep_for(seconds{s}); | |
}; | |
queue<string> message_queue; | |
condition_variable mcond; | |
mutex mmutex; | |
// Thanks to Aram Gevorgyan for the spurious condition variable wake up issue | |
// pointed out | |
bool data_pushed = false; | |
auto consumer = [&do_wait, &mmutex, &mcond, &message_queue, | |
&data_pushed]() -> void { | |
while (true) { | |
do_wait(4); | |
string *m = nullptr; | |
{ | |
unique_lock<mutex> lck{mmutex}; | |
mcond.wait(lck, [&]() -> bool { return data_pushed; }); | |
data_pushed = false; | |
string **h = &m; | |
*h = &message_queue.front(); | |
message_queue.pop(); | |
} | |
printf("Pulled: %s in consumer thread\n", m->c_str()); | |
} | |
}; | |
int counter{0}; | |
auto producer = [&mmutex, &message_queue, &mcond, &counter, &do_wait, | |
&data_pushed]() { | |
while (true) { | |
do_wait(2); | |
{ | |
unique_lock<mutex> lck{mmutex}; | |
stringstream ss; | |
ss << ++counter; | |
message_queue.push(ss.str()); | |
data_pushed = true; | |
} | |
printf("Producer sent: %d\n", counter); | |
mcond.notify_one(); | |
} | |
}; | |
thread t1{consumer}; | |
thread t2{producer}; | |
t1.join(); | |
t2.join(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment