#include <boost/thread.hpp>
#include <unistd.h>
#include <stdio.h>
#include <queue>
template<typename Data>
class concurrent_queue
{
private:
std::queue<Data> the_queue;
mutable boost::mutex the_mutex;
boost::condition_variable the_condition_variable;
public:
void push(Data const& data) {
boost::mutex::scoped_lock lock(the_mutex);
the_queue.push(data);
lock.unlock();
the_condition_variable.notify_one();
}
bool empty() const {
boost::mutex::scoped_lock lock(the_mutex);
return the_queue.empty();
}
bool try_pop(Data& popped_value) {
boost::mutex::scoped_lock lock(the_mutex);
if(the_queue.empty()) {
return false;
}
popped_value=the_queue.front();
the_queue.pop();
return true;
}
void wait_and_pop(Data& popped_value) {
boost::mutex::scoped_lock lock(the_mutex);
while(the_queue.empty()) {
the_condition_variable.wait(lock);
}
popped_value=the_queue.front();
the_queue.pop();
}
size_t size() const {
boost::mutex::scoped_lock lock(the_mutex);
return the_queue.size();
}
};
concurrent_queue<int> queue;
class threadObj
{
public:
void operator()() {
run();
}
protected:
virtual void run() = 0;
};
class threadProducer : public threadObj
{
private:
void run() {
for(int i = 0; i < 100; i++) {
usleep(20*1000);
queue.push(i);
printf("producer: %d\n", i);
}
}
};
class threadConsumer : public threadObj
{
private:
void run() {
for(int i = 0; i < 100; i++) {
int j = 0;
queue.wait_and_pop(j);
printf("\t\tconsumer: %d\n", j);
usleep(10*1000);
}
}
};
int main(int argc, char *argv[])
{
printf("MAIN START\n");
boost::thread *consumer = new boost::thread(threadConsumer());
boost::thread *producer = new boost::thread(threadProducer());
producer->join();
consumer->join();
printf("MAIN END\n");
return 0;
}