如何通知 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() 立即返回? 的相关文章

  • 注销租约抛出 InvalidOperationException

    我有一个使用插件的应用程序 我在另一个应用程序域中加载插件 我使用 RemoteHandle 类http www pocketsilicon com post Things That Make My Life Hell Part 1 App
  • MVC 在布局代码之前执行视图代码并破坏我的脚本顺序

    我正在尝试将所有 javascript 包含内容移至页面底部 我正在将 MVC 与 Razor 一起使用 我编写了一个辅助方法来注册脚本 它按注册顺序保留脚本 并排除重复的内容 Html RegisterScript scripts som
  • 使用 Newtonsoft 和 C# 反序列化嵌套 JSON

    我正在尝试解析来自 Rest API 的 Json 响应 我可以获得很好的响应并创建了一些类模型 我正在使用 Newtonsoft 的 Json Net 我的响应中不断收到空值 并且不确定我的模型设置是否正确或缺少某些内容 例如 我想要获取
  • 如何创建包含 IPv4 地址的文本框? [复制]

    这个问题在这里已经有答案了 如何制作一个这样的文本框 我想所有的用户都见过这个并且知道它的功能 您可以使用带有 Mask 的 MaskedTestBox000 000 000 000 欲了解更多信息 请参阅文档 http msdn micr
  • 回发后刷新时提示确认表单重新提交。我做错了什么?

    我有一个以空白 默认状态启动的仪表板 我让用户能够将保存的状态加载到仪表板中 当他们单击 应用 按钮时 我运行以下代码 function CloseAndSave var radUpload find radUpload1ID var in
  • 如何使用 LINQ2SQL 连接两个不同上下文的表?

    我的应用程序中有 2 个数据上下文 不同的数据库 并且需要能够通过上下文 B 中的表的右连接来查询上下文 A 中的表 我该如何在 LINQ2SQL 中执行此操作 Why 我们正在使用 SaaS 产品来跟踪我们的时间 项目等 并希望向该产品发
  • 在 Visual Studio 2010 中从 Fortran 调用 C++ 函数

    我想从 Fortran 调用 C 函数 为此 我在 Visual Studio 2010 中创建了一个 FORTRAN 项目 之后 我将一个 Cpp 项目添加到该 FORTRAN 项目中 当我要构建程序时出现以下错误 Error 1 unr
  • qdbusxml2cpp 未知类型

    在使用 qdbusxml2cpp 程序将以下 xml 转换为 Qt 类时 我收到此错误 qdbusxml2cpp c ObjectManager a ObjectManager ObjectManager cpp xml object ma
  • 为什么调用非 const 成员函数而不是 const 成员函数?

    为了我的目的 我尝试包装一些类似于 Qt 共享数据指针的东西 经过测试 我发现当应该调用 const 函数时 会选择它的非 const 版本 我正在使用 C 0x 选项进行编译 这是一个最小的代码 struct Data int x con
  • 标准化 UTF-8 到底是什么?

    The 重症监护室项目 http userguide icu project org transforms normalization 现在也有一个PHP库 http us php net manual en class normalize
  • Qt - ubuntu中的串口名称

    我在 Ubuntu 上查找串行端口名称时遇到问题 如您所知 为了在 Windows 上读取串口 我们可以使用以下代码 serial gt setPortName com3 但是当我在 Ubuntu 上编译这段代码时 我无法使用这段代码 se
  • Azure 辅助角色“请求输入之一超出范围”的内部异常。

    我在辅助角色中调用 CloudTableClient CreateTableIfNotExist 方法 但收到一个异常 其中包含 请求输入之一超出范围 的内部异常 我做了一些研究 发现这是由于将表命名为非法表名引起的 但是 我尝试为我的表命
  • 等待进程释放文件

    我如何等待文件空闲以便ss Save 可以用新的覆盖它吗 如果我紧密地运行两次 左右 我会得到一个generic GDI error
  • “接口”类似于 boost::bind 的语义

    我希望能够将 Java 的接口语义与 C 结合起来 起初 我用过boost signal为给定事件回调显式注册的成员函数 这非常有效 但后来我发现一些函数回调池是相关的 因此将它们抽象出来并立即注册所有实例的相关回调是有意义的 但我了解到的
  • 动态添加 ASP.Net 控件

    我有一个存储过程 它根据数据库中存储的记录数返回多行 现在我想有一种方法来创建 div 带有包含该行值的控件的标记 如果从数据库返回 10 行 则 10 div 必须创建标签 我有下面的代码来从数据库中获取结果 但我不知道如何从这里继续 S
  • Cmake 链接共享库:包含库中的头文件时“没有这样的文件或目录”

    我正在学习使用 CMake 构建库 构建库的代码结构如下 include Test hpp ITest hpp interface src Test cpp ITest cpp 在 CMakeLists txt 中 我用来构建库的句子是 f
  • 为什么 gcc 抱怨“错误:模板参数 '0' 的类型 'intT' 取决于模板参数”?

    我的编译器是gcc 4 9 0 以下代码无法编译 template
  • C++ 函数重载类似转换

    我收到一个错误 指出两个重载具有相似的转换 我尝试了太多的事情 但没有任何帮助 这是那段代码 CString GetInput int numberOfInput BOOL clearBuffer FALSE UINT timeout IN
  • 如何从 ODBC 连接获取可用表的列表?

    在 Excel 中 我可以转到 数据 gt 导入外部数据 gt 导入数据 然后选择要使用的数据源 然后在提供登录信息后 它会给我一个表格列表 我想知道如何使用 C 以编程方式获取该列表 您正在查询什么类型的数据源 SQL 服务器 使用权 看
  • 当从finally中抛出异常时,Catch块不会被评估

    出现这个问题的原因是之前在 NET 4 0 中运行的代码在 NET 4 5 中因未处理的异常而失败 部分原因是 try finallys 如果您想了解详细信息 请阅读更多内容微软连接 https connect microsoft com

随机推荐

  • 如何正确转义 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 超时 这样我就不需要继续轮询 请