// cond_var.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "cond_var.h" #include <vector> #include <list> #include <fstream> #include <boost/utility.hpp> #include <boost/thread/thread.hpp> #include <boost/thread/condition.hpp> #include <boost/bind.hpp> #include <boost/format.hpp> #include <boost/date_time/posix_time/posix_time.hpp> #ifdef _DEBUG #define new DEBUG_NEW #endif // The one and only application object CWinApp theApp; using namespace std; // thread-safe async list with condition_variable class async_queue { private: list<string> _cmdList; boost::condition_variable _ready; boost::mutex _mtx; public: void post(const string& cmd) { boost::mutex::scoped_lock lk(_mtx); _cmdList.push_back(cmd); _ready.notify_one(); } string get() { boost::mutex::scoped_lock lk(_mtx); while(_cmdList.empty()) _ready.wait(lk); string ret = _cmdList.front(); _cmdList.pop_front(); return ret; } / // original version void sync_post(const string& cmd) { boost::mutex::scoped_lock lk(_mtx); _cmdList.push_back(cmd); } string sync_get() { boost::mutex::scoped_lock lk(_mtx); boost::this_thread::sleep(boost::posix_time::seconds(1)); if(_cmdList.empty()) return ""; string ret = _cmdList.front(); _cmdList.pop_front(); return ret; } / }; async_queue cmdlist; void output(const string &val) { static boost::mutex mut; boost::mutex::scoped_lock lk(mut); cout << val << endl; } void producer() { for(int i = 0; i < 20; i++) { string val = (boost::format("command %d")%i).str(); cmdlist.post(val); output("enqueue " + val); } string tm = boost::posix_time::to_iso_string(boost::get_system_time()); output("end time = " + tm); } void consumer() { ofstream file("D://test.txt"); while(true) { string cmd = cmdlist.get(); boost::this_thread::sleep(boost::posix_time::seconds(1)); string tm = boost::posix_time::to_iso_string(boost::get_system_time()); file << tm << "," << cmd << endl; output("get " + cmd); } } void sync_producer() { for(int i = 0; i < 10; i++) { string val = (boost::format("command %d")%i).str(); cmdlist.sync_post(val); boost::this_thread::sleep(boost::posix_time::millisec(100)); output("enqueue " + val); } string tm = boost::posix_time::to_iso_string(boost::get_system_time()); output("end time = " + tm); } void sync_consumer() { while(true) { string cmd = cmdlist.sync_get(); if(!cmd.empty()) { //boost::this_thread::sleep(boost::posix_time::seconds(1)); output("get " + cmd); } } } int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { boost::thread thrd2(consumer); boost::thread thrd1(producer); //boost::thread thrd2(sync_consumer); //boost::thread thrd1(sync_producer); thrd1.join(); thrd2.join(); return 0; }