Skip to content

Instantly share code, notes, and snippets.

@juehan
Created January 24, 2013 02:49
Show Gist options
  • Save juehan/4617270 to your computer and use it in GitHub Desktop.
Save juehan/4617270 to your computer and use it in GitHub Desktop.
Consumer - producer example using C++11 thread
#include <condition_variable>
#include <mutex>
#include <future>
#include <iostream>
#include <chrono>
#include <queue>
bool isReady;
std::mutex mutex;
std::condition_variable condvar;
std::queue<int> messageQ;
void Producer()
{
std::cout << "=== Producer ===" << std::endl;
for (auto x = 0; x < 10; x++)
{
std::lock_guard<std::mutex> guard(mutex);
std::cout << "Producing message: " << x << " th" << std::endl;
messageQ.push(x);
std::this_thread::sleep_for(std::chrono::seconds(1));
}
{
std::lock_guard<std::mutex> guard(mutex);
isReady = true;
}
std::cout << "=== Producer has completed ===" << std::endl;
condvar.notify_one();
}
void Consumer()
{
{
std::unique_lock<std::mutex> ulock(mutex);
condvar.wait(ulock, [] {
return isReady; }
);
}
std::cout << "\n\n=== Consumer is ready to get message ===" << std::endl;
while(!messageQ.empty())
{
std::lock_guard<std::mutex> guard(mutex);
int i = messageQ.front();
std::cout << "Consuming message: " << i << " th" << std::endl;
messageQ.pop();
}
if(!messageQ.empty())
std::cout << "There are still messages remained from producer" << std::endl;
else
std::cout << "All messages from producer has been processed" << std::endl;
}
int main()
{
auto t1 = std::async(std::launch::async, Producer);
auto t2 = std::async(std::launch::async, Consumer);
t1.get();
t2.get();
}
@attardi
Copy link

attardi commented Feb 9, 2015

It is unsafe to check
while(!messageQ.empty())
outside of a guard: the queue might become empty immediately after the check.

@yzhong52
Copy link

yzhong52 commented May 6, 2015

@attardi, yay, it is true. std::queue is not thread safe at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment