jas*_*mar 4 c++ boost boost-asio
此代码调用发布的句柄
boost::asio::io_context ioc;
boost::asio::post(ioc, []{ std::cout << "lol" << std::endl; });
ioc.poll();
Run Code Online (Sandbox Code Playgroud)
而这并没有:
boost::asio::io_context ioc;
ioc.poll(); // empty, set internal state to stopped_
boost::asio::post(ioc, []{ std::cout << "lol" << std::endl; });
ioc.poll(); // doesn't work as stopped() now returns true
Run Code Online (Sandbox Code Playgroud)
是设计使然吗?如果是,为什么?我可以io_context通过某种方式配置来改变这种行为吗?
io_service/io_context 被设计为在用完工作\xc2\xb9 时停止。
\n的文档io_service包含io_context:
\n\n阻止 io_context 耗尽工作
\n某些应用程序可能需要阻止 io_context 对象的 run() 调用在没有更多工作要做时返回。例如,io_context 可能在应用程序的异步操作之前启动的后台线程中运行。run() 调用可以通过创建 boost::asio::executor_work_guard<io_context::executor_type> 类型的对象来保持运行:
\nRun Code Online (Sandbox Code Playgroud)\nboost::asio::io_context io_context;\nboost::asio::executor_work_guard<boost::asio::io_context::executor_type>\n = boost::asio::make_work_guard(io_context);\n...\n为了实现关闭,应用程序需要调用 io_context 对象的 stop() 成员函数。这将导致 io_context run() 调用尽快返回,放弃未完成的操作,并且不允许分派就绪处理程序。
\n或者,如果应用程序要求允许所有操作和处理程序正常完成,则可以显式重置工作对象。
\nRun Code Online (Sandbox Code Playgroud)\nboost::asio::io_context io_context;\nboost::asio::executor_work_guard<boost::asio::io_context::executor_type>\n = boost::asio::make_work_guard(io_context);\n...\nwork.reset(); // Allow run() to exit.\n
请注意,“老式”Asio 接口使用了不太通用的io_service::work对象:
io_service ios;\nio_service::work work(ios); // old interface!\nRun Code Online (Sandbox Code Playgroud)\n这将需要您做额外的工作才能重置它:
\nasio::io_service ios;\nstd::optional<asio::io_service::work> work(ios);\n// ...\nwork.reset();\nRun Code Online (Sandbox Code Playgroud)\n最后,当上下文确实无法工作时,您必须restart()在重新使用它之前执行它:
我认为设计的基本原理来自于库对服务如何在调度和线程方面运行没有任何意见,并保证io_context/io_service必须是线程安全的 xc2xb2。请参阅文档了解\nbackground。
\xc2\xb9 旁注:同样,thread_pool(is-a就像 isexecution_context一样io_context)不是为重用而设计的(参见例如Boost asio thread_pool join does not wait fortasks to be finish)
\xc2\xb2 当然,除了对象生命周期(构造/销毁)
\n