Boost.Asioでio_service::run()を包含する設計
Boost.Asio io_serviceを包含する設計 - Faith and Brave - C++で遊ぼう
上の話に加えて、io_service::run()を誰が呼ぶかという話についてのメモ。
1つは上で紹介されているように、io_serviceを公開し、ユーザーにrun()させるパターン。
class client { public: client() : m_io_service(new boost::asio::io_service()) {} explicit client(boost::asio::io_service &io_service) : m_io_service(&io_service, [](boost::asio::io_service *) {}) {} boost::asio::io_service &get_io_service() const noexcept { return *m_io_service; } void start() { // ... } private: std::shared_ptr<boost::asio::io_service> m_io_service; }; void f() { client client_; client_.start(); client_.get_io_service().run(); }
もう1つはcpp-netlibがそうしているように、自分がio_serviceを作った場合は自分でrun()するパターン。
class client { public: client() : m_io_service(new boost::asio::io_service()), // run()がすぐ終了しないよう、workを注入する m_work(new boost::asio::io_service(*m_io_service)), // スレッドを立ててrun()を呼び出す m_thread([=] { m_io_service->run(); }) {} explicit client(boost::asio::io_service &io_service) : m_io_service(&io_service, [](boost::asio::io_service *) {}) {} ~client() { if (m_work) { cancel(); // workを削除して、run()が終了できるようにする m_work.reset(); // run()の終了を待つ m_thread.join(); } } void start() { // ... } private: std::shared_ptr<boost::asio::io_service> m_io_service; std::unique_ptr<boost::asio::io_service::work> m_work; std::thread m_thread; };
どちらを使うかはお好みです。
なお個人的には常にio_serviceを渡してもらえばいいと思っているもよう。