微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

防止boost :: asio :: io_context在空轮询中停止 阻止io_context耗尽工作

如何解决防止boost :: asio :: io_context在空轮询中停止 阻止io_context耗尽工作

代码称为发布的句柄

    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

Live example

是设计使然吗?如果是,为什么?我可以通过某种方式配置io_context来更改此行为吗?

解决方法

此文档(不是最佳位置,应在poll文档中提及):

io_context::restart - develop

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_serviceio_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()进行重用:

enter image description here

理性

我认为设计的理由来自没有任何图书馆的图书馆 关于如何在调度和线程方面运行服务的意见, 结合保证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)>

²当然,除了对象生命期(构造/破坏)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?