防止 boost::asio::io_context 在空轮询调用时停止

2024-05-15

此代码调用发布的句柄

    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

实例 https://wandbox.org/permlink/yZSyHEQPVj2FG2sS

是设计使然吗?如果是,为什么?我可以配置吗io_context以某种方式改变这种行为?


io_service/io_context 被设计为在工作耗尽时停止。

的文档io_service https://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/reference/io_service.html#boost_asio.reference.io_service.stopping_the_io_context_from_running_out_of_work and io_context https://www.boost.org/doc/libs/1_73_0/doc/html/boost_asio/reference/io_context.html#boost_asio.reference.io_context.stopping_the_io_context_from_running_out_of_work包含:

阻止 io_context 耗尽工作

当没有更多工作要做时,某些应用程序可能需要阻止 io_context 对象的 run() 调用返回。例如,io_context 可能在应用程序的异步操作之前启动的后台线程中运行。 run() 调用可以通过创建 boost::asio::executor_work_guard<:executor_type> 类型的对象来保持运行:

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 object:

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必须是 线程安全²。看文档用于 背景 https://www.boost.org/doc/libs/1_73_0/doc/html/boost_asio/overview/core/threads.html.


1 旁注:同样,thread_pool(这是-aexecution_context就像io_contextis) 不是为重复使用而设计的(参见例如Boost asio thread_pool join不等待任务完成 https://stackoverflow.com/questions/61328430/boost-asio-thread-pool-join-does-not-wait-for-tasks-to-be-finished/62399256#62399256)

² 当然,对象生命周期(构造/销毁)除外

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

防止 boost::asio::io_context 在空轮询调用时停止 的相关文章

  • 如何获取正在访问 ASP.NET 应用程序的当前用户?

    为了获取系统中当前登录的用户 我使用以下代码 string opl System Security Principal WindowsIdentity GetCurrent Name ToString 我正在开发一个 ASP NET 应用程
  • 通过 CMIS (dotCMIS) 连接到 SP2010:异常未经授权

    我正在使用 dotCMIS 并且想要简单连接到我的 SP2010 服务器 我尝试用 C 来做到这一点 如下所示http chemistry apache org dotnet getting started with dotcmis htm
  • WCF RIA 服务 - 加载多个实体

    我正在寻找一种模式来解决以下问题 我认为这很常见 我正在使用 WCF RIA 服务在初始加载时将多个实体返回给客户端 我希望两个实体异步加载 以免锁定 UI 并且我想利用 RIA 服务来执行此操作 我的解决方案如下 似乎有效 这种方法会遇到
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • 对现有视频添加水印

    我正在寻找一种用 C 在视频上加水印的方法 就像在上面写文字一样 图片或文字标签 我该怎么做 谢谢 您可以使用 Nreco 视频转换器 代码看起来像 NReco VideoConverter FFMpegConverter wrap new
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • 是否可以在 .NET Core 中将 gRPC 与 HTTP/1.1 结合使用?

    我有两个网络服务 gRPC 客户端和 gRPC 服务器 服务器是用 NET Core编写的 然而 客户端是托管在 IIS 8 5 上的 NET Framework 4 7 2 Web 应用程序 所以它只支持HTTP 1 1 https le
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐