Skip to content

Instantly share code, notes, and snippets.

@fxfactorial
Last active June 10, 2018 15:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fxfactorial/ada1ed6377b1f014811233b5ac368028 to your computer and use it in GitHub Desktop.
Save fxfactorial/ada1ed6377b1f014811233b5ac368028 to your computer and use it in GitHub Desktop.
Producer and Consumer threads using Condition variable and mutex
// 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