C++ 防止boost::asio::io\u上下文在空轮询调用时停止
此代码调用已发布的句柄C++ 防止boost::asio::io\u上下文在空轮询调用时停止,c++,boost,boost-asio,C++,Boost,Boost Asio,此代码调用已发布的句柄 boost::asio::io\u上下文ioc; boost::asio::post(ioc,[]{std::cout这是一篇文档(不是在最佳位置,应该在poll文档中提及): 重新启动以准备后续的run()调用 无效重新启动() 当由于停止或工作不足而返回以前对这些函数的调用时,run()、run\u one()、poll()或poll\u one()函数的任何第二次或以后的调用都必须在调用这些函数之前调用此函数,对象的stopped()函数将返回false 当对ru
boost::asio::io\u上下文ioc;
boost::asio::post(ioc,[]{std::cout这是一篇文档(不是在最佳位置,应该在poll
文档中提及):
重新启动以准备后续的run()
调用
无效重新启动()
当由于停止或工作不足而返回以前对这些函数的调用时,run()
、run\u one()
、poll()
或poll\u one()
函数的任何第二次或以后的调用都必须在调用这些函数之前调用此函数
,对象的stopped()
函数将返回false
当对run()
、run\u one()
、poll()
或poll\u one()函数有任何未完成的调用时,不得调用此函数
因此,基本上您需要添加重新启动
,以使其正常工作
以下是原因。io_服务/io_上下文被设计为在它们用完工作时停止
用于和包含以下内容的文档:
正在停止io_上下文,以防其无法工作
有些应用程序可能需要防止io_上下文对象的run()调用在没有更多工作要做时返回。例如,io_上下文可能正在后台线程中运行,该线程在应用程序异步操作之前启动。run()可以通过创建boost::asio::executor\u work\u guard类型的对象来保持调用的运行:
这将需要您进行额外的工作,以便能够重置它:
asio::io_service ios;
std::optional<asio::io_service::work> work(ios);
// ...
work.reset();
asio::io\u服务ios;
std::可选
根本原因
我认为设计的理由来自图书馆没有任何
关于如何在调度和线程方面运行服务的意见
结合保证io\u上下文
/io\u服务
必须
线程安全²。请参阅
旁注:同样地,线程池
(与io\u上下文
一样,它是一个执行上下文
)也不是为重复使用而设计的(参见示例)
²除了对象生存期(构造/销毁)之外,当然值得添加:重新启动
函数不会删除等待就绪的处理程序。不过,我不知道为什么界面会这样设计。这不是我所期望的。只需使用工作保护(asio::io\u service::work
,或者更现代的make\u executor\u work\u guard
helper)这正是我一直在寻找的。从未在文档中看到过。你能给出答案吗?@jaskmar(我还错误地记得make\u work\u guard
的名字-这个类确实是exucutor\u work\u guard
)顺便说一句,在新的执行器模型中,可以通过实现为no-op来实现不依赖于工作的执行器。但是这有点进入了扩展/实现领域。
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.
io_service ios;
io_service::work work(ios); // old interface!
asio::io_service ios;
std::optional<asio::io_service::work> work(ios);
// ...
work.reset();