優先度付きio_service
io_serviceに優先度付けてpost出来ないもんかなぁと思ってたんですが、
strandの実装を真似ればいいんだ、と気が付きました。
#include <queue> #include <map> #include <boost/asio.hpp> #include <boost/bind.hpp> #include <boost/foreach.hpp> #include <boost/thread.hpp> class priority{ boost::asio::io_service &io; typedef boost::function<void ()> CompletionHandler; typedef std::queue<const CompletionHandler> CompletionHandlerArray; typedef std::map<int, CompletionHandlerArray> CompletionHandlerArrayMap; CompletionHandlerArrayMap priorityhandler; boost::mutex mutex; void worker(){ boost::mutex::scoped_lock lk(mutex); BOOST_FOREACH(CompletionHandlerArrayMap::reference ref, priorityhandler){ if ( ! ref.second.empty()){ CompletionHandler front = ref.second.front(); ref.second.pop(); lk.unlock(); front(); break; } } } public: priority(boost::asio::io_service &io):io(io),priorityhandler(){} ~priority(){} void post(int p, const CompletionHandler &handler){ boost::mutex::scoped_lock lk(mutex); priorityhandler[p].push(handler); io.post(boost::bind(&priority::worker, this)); } };
使い方はこんな感じ
int main(){ boost::asio::io_service io; priority pri(io); for (int i = 0; i < 100; i++){ int p = i % 5; pri.post(p, [=](){ std::cout << "priority:" << p << " number:" << i << std::endl; boost::this_thread::sleep(boost::posix_time::millisec(10)); } ); } io.run(); return 0; }