问题描述
此代码称为发布的句柄
boost::asio::io_context ioc;
boost::asio::post(ioc,[]{ std::cout << "lol" << std::endl; });
ioc.poll();
而事实并非如此:
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
是设计使然吗?如果是,为什么?我可以通过某种方式配置io_context
来更改此行为吗?
解决方法
此文档(不是最佳位置,应在poll
文档中提及):
io_context::restart重新启动
io_context
,以准备后续的run()
调用。void restart();
在先前调用
run()
,run_one()
,poll()
或poll_one()
函数的第二次或更多次调用之前,必须先调用此函数由于io_context
被停止或没有工作而返回。调用restart()
之后,io_context
对象的stopped()
函数将返回false
。在未完成对
run()
,run_one()
,poll()
或poll_one()
函数的调用时,不得调用此函数。
因此,基本上,您需要添加restart
才能使其正常工作。
https://wandbox.org/permlink/aXzz5GCAIMIvStnl
这是an extra clue原因。
,io_service / io_context旨在在它们用尽时停止工作。
io_service
和io_context
的文档包含:
阻止io_context耗尽工作
某些应用程序可能需要在没有更多工作要做时阻止io_context对象的run()调用返回。例如,io_context可能在后台线程中运行,该后台线程在应用程序的异步操作之前启动。可以通过创建类型为boost :: asio :: executor_work_guard
的对象来保持run()调用的运行。: boost::asio::io_context io_context; boost::asio::executor_work_guard<boost::asio::io_context::executor_type> = boost::asio::make_work_guard(io_context); ...
要实现关闭,应用程序将需要调用io_context对象的stop()成员函数。这将导致io_context run()调用尽快返回,放弃未完成的操作,并且不允许分派就绪的处理程序。
或者,如果应用程序要求允许所有操作和处理程序正常完成,则可以显式重置工作对象。
boost::asio::io_context io_context; boost::asio::executor_work_guard<boost::asio::io_context::executor_type> = boost::asio::make_work_guard(io_context); ... work.reset(); // Allow run() to exit.
请注意,“老式”的Asio接口使用了一个不太通用的io_service::work
对象:
io_service ios;
io_service::work work(ios); // old interface!
这将需要您做一些额外的工作才能重置它:
asio::io_service ios;
std::optional<asio::io_service::work> work(ios);
// ...
work.reset();
重新启动
最后,当上下文 did 用尽时,您将必须restart()
进行重用:
理性
我认为设计的理由来自没有任何图书馆的图书馆
关于如何在调度和线程方面运行服务的意见,
结合保证io_context
/ io_service
必须是
线程安全²。参见docs for
background。
¹旁注:同样,thread_pool
(就像execution_context
一样是io_context
)不是为了重复使用而设计的(例如参见Boost asio thread_pool join does not wait for tasks to be finished)>
²当然,除了对象生命期(构造/破坏)