如何通知 select() 立即返回?

2024-01-09

我有一个工作线程正在侦听 TCP 套接字以获取传入流量,并缓冲接收到的数据以供主线程访问(我们将此套接字称为A)。但是,即使没有数据传入,工作线程也必须执行一些常规操作(例如每秒一次)。因此,我使用select()超时,这样我就不需要继续轮询。 (请注意,调用receive()在非阻塞套接字上然后休眠一秒钟并不好:传入的数据应该立即可供主线程使用,即使主线程可能并不总是能够立即处理它,因此需要缓冲。 )

现在,我还需要能够向工作线程发出信号以立即执行其他操作;从主线程,我需要使工作线程select()立即返回。目前,我已经解决了这个问题如下(方法基本上采用自here http://mail.python.org/pipermail/python-list/2002-May/147063.html and here http://www.developerweb.net/forum/showthread.php?t=5154):

在程序启动时,工作线程为此目的创建一个数据报(UDP)类型的附加套接字,并将其绑定到某个随机端口(我们称此套接字为B)。同样,主线程创建一个用于发送的数据报套接字。在其呼吁中select(),工作线程现在列出了两者A and B in the fd_set。当主线程需要发出信号时,sendto()是几个字节到相应的端口localhost。回到工作线程,如果B仍留在fd_set after select()返回,则recvfrom()被调用并且接收到的字节被简单地忽略。

这似乎工作得很好,但我不能说我喜欢这个解决方案,主要是因为它需要绑定一个额外的端口B,而且还因为它添加了几个额外的套接字 API 调用,我猜这些调用可能会失败 - 而且我真的不想为每种情况找出适当的操作。

我认为理想情况下,我想调用一些需要的函数A作为输入,除了使select()立即返回。但是,我不知道这样的功能。 (我想我可以例如shutdown()套接字,但副作用是不能接受的:)

如果这是不可能的,第二个最佳选择是创建一个B它比真正的 UDP 套接字要虚拟得多,并且实际上不需要分配任何有限的资源(超出合理的内存量)。我猜Unix 域套接字 http://en.wikipedia.org/wiki/Unix_domain_sockets确实会这样做,但是:该解决方案的跨平台性不应比我目前拥有的少得多,尽管有一定数量的#ifdef东西很好。 (我主要针对 Windows 和 Linux – 顺便编写 C++。)

请不要建议重构以消除两个单独的线程。这种设计是必要的,因为主线程可能会被阻塞很长一段时间(例如,进行一些密集的计算 - 并且我无法开始定期调用receive()来自最内层的计算循环),同时,有人需要缓冲传入的数据(并且由于我无法控制的原因,它不能是发送者)。

现在写到这里,我发现肯定有人会简单地回复“Boost.Asio http://www.boost.org/doc/libs/1_37_0/doc/html/boost_asio.html“,所以我只是第一次看到它......不过,找不到明显的解决方案。请注意,我也不能(轻易)影响套接字的方式A已创建,但如果需要,我应该能够让其他对象包装它。


你快到了。用一个“自管”技巧 http://cr.yp.to/docs/selfpipe.html。打开一个管道,将其添加到您的select()读和写fd_set,从主线程写入它以解锁工作线程。它可以跨 POSIX 系统移植。

我在一个系统中看到了 Windows 类似技术的变体(实际上与上面的方法一起使用,用#ifdef WIN32)。可以通过添加一个虚拟(未绑定)数据报套接字来实现解除阻塞fd_set然后关闭它。当然,缺点是每次都必须重新打开它。

然而,在上述系统中,这两种方法的使用都相当谨慎,并且用于意外事件(例如,信号、终止请求)。首选方法仍然是可变超时select(),取决于为工作线程安排某事的时间。

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

如何通知 select() 立即返回? 的相关文章

随机推荐

  • 如何正确转义 Makefile 的数据?

    我正在动态生成config mk带有将由 Makefile 使用的 bash 脚本 该文件的构造如下 cat gt config mk lt
  • DMA 与中断驱动的 I/O

    我不太清楚 DMA 和中断 I O 之间的区别 当前正在阅读操作系统概念 第 7 版 具体来说 我不确定在这两种情况下何时会发生中断 以及在这两种情况下 CPU 在什么时候可以自由地执行其他工作 我一直在读但不一定能调和的东西 中断驱动 通
  • 为什么 ICC 在 x86 上的汇编中生成“inc”而不是“add”?

    在摆弄简单的 C 代码时 我注意到一些奇怪的事情 ICC为何产生incl eax在为增量生成的汇编代码中而不是addl 1 eax 不过 GCC 的行为符合预期 使用add 示例代码 O3用于 GCC 和 ICC int A B C D E
  • 如何在 Windows 上使用 GCC 11.1 构建 Qt 5.13.2?

    我已经使用 GCC MinGW w64 在 Windows 上成功构建 Qt 5 很长时间了 当我在 GCC 11 1 上尝试相同的操作时 构建失败并出现奇怪的错误消息 我该怎么做才能让它发挥作用 我自己使用以下方法构建了编译器develo
  • 是否可以在不进行额外分配的情况下移动和修改向量?

    考虑以下代码 let u Vec
  • 文件恢复软件如何工作?

    我想做一些简单的文件恢复软件 我想尝试恢复通过按 Shift Delete 删除的文件 我在 Windows 中工作 任何人都可以向我展示任何可以帮助我以编程方式执行此操作的链接或文档吗 我了解 C C NET 有什么指点吗 据我所知 文件
  • Python Poetry 的依赖版本语法

    The Poetry https github com sdispater poetry项目是Python的依赖管理系统 它使用新的pyproject toml https www python org dev peps pep 0518
  • 从 CloudKit 获取 CKAsset 图像非常慢

    我使用 CloudKit 作为我的 iOS 应用程序的服务器后端 我用它来容纳一些相对静态的数据以及一些图像 CKAsset 当我需要从公共数据库中实际获取这些资产时 我遇到了问题 它们的加载速度极其缓慢 我的用例是将图像加载到集合视图内的
  • 如何从 std::thread 更改 GUI?

    首先 我尝试使用setVisible from thread 有一个事件 void MainWindow OnShow Start OnShow actions ui gt LoadingBox gt setVisible true std
  • 如何让 Observable 返回转换后的项目数组 (Rxjs)

    我有一个生成 json 产品列表的端点 我在产品代码中定义了一个自定义类类型 我试图从端点获取数据 并将产品的 json 数组转换为 Product 类的数组 示例 API json 根据我的实际数据简化 products id 1 nam
  • 多次打开和关闭 php 标签会增加页面负载吗? [复制]

    这个问题在这里已经有答案了 可能的重复 开始 结束标签和性能 https stackoverflow com questions 2437144 opening closing tags performance 这是一个新手问题 但我在网上
  • Python `in` 与 `__contains__` 的功能

    我实施了 contains 前几天第一次在课堂上使用该方法 但其行为并不符合我的预期 我怀疑其中有一些微妙之处in https docs python org 2 library operator html我不明白的运算符 我希望有人能启发
  • 通过静态构造函数创建 ALV 时的 NULL 对象引用。为什么?

    我正在尝试运行从教程复制的这个程序 但我在这一行得到 Null 异常 CALL METHOD list gt SET TABLE FOR FIRST DISPLAY 我的理解是列表对象应该在类构造函数中创建 Method CLASS CON
  • Postman 获取环境名称作为变量

    我想知道是否可以将环境名称作为 Postman 中的环境变量 目前 我正在每个环境的环境变量中手动设置它 但它可以从某种应用程序变量中检索 这会很棒 我在文档中找不到任何内容 这应该为您提供当前选择的环境的名称 pm environment
  • PHP 中的 DOM 文档

    我刚刚开始阅读有关 DOM 的文档和示例 以便抓取和解析文档 例如 我的部分文档如下所示 div table tr td Crap td tr tr td width 172 valign top a href link img heigh
  • 为什么 PEP-8 指定最大行长度为 79 个字符? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 将参数传递到 ASP .NET 页面

    我最近开始使用 ASP NET 但我对其他 NET 框架非常熟悉 我正在开发的应用程序需要将字符串索引作为命令行样式参数 现在 在我的 Page 类中 我有一个 const 字符串 我将其用作占位符 所以我的问题是两个人 1 如何设置应用程
  • 不使用 Visual Studio 创建 Windows 服务

    因此 使用 Visual Studio 创建 Windows 服务相当简单 我的问题更深入一些 即什么实际上使可执行文件可作为服务安装以及如何将服务编写为直接的 C 应用程序 我找不到很多关于此的参考资料 但我假设必须有一些我可以实现的接口
  • 使用Vite构建的React组件库会生成一大堆style.css,如何拆分它或注入样式?

    我目前正在重写组件库的构建步骤以使用 Vite 我遇到了有关样式的问题 它们没有被拆分 而是捆绑到一个大的 style css 文件中 这给我带来了两个问题 当我将包安装到另一个项目中时 它不会自动包含在内 如果我导入一个组件 style
  • 如何通知 select() 立即返回?

    我有一个工作线程正在侦听 TCP 套接字以获取传入流量 并缓冲接收到的数据以供主线程访问 我们将此套接字称为A 但是 即使没有数据传入 工作线程也必须执行一些常规操作 例如每秒一次 因此 我使用select 超时 这样我就不需要继续轮询 请