Linux:应用程序响应能力和select()

Linux: application responsiveness and select()

本文关键字:select 能力 应用程序 响应 Linux      更新时间:2023-10-16

我有一个C++控制台应用程序,它使用open() [O_RDWR | O_NONBLOCK]write()select()read()close()来处理设备文件。也可以调用ioctl()来取消当前操作。在任何给定时间,只有一个用户可以使用设备。

我需要想出C++类,其中包含libsigc ++信号,当设备中的数据可用时,这些信号会被触发。

问题:调用select()应用程序在等待数据时变得无响应。如何使其响应 - 通过在工作线程中调用select()?如果是这样 - 工作线程将如何与主线程通信?也许我应该研究一下boost::asio

如何使其响应 - 通过在工作线程中调用 select()

您可以使用 dup(),这将复制您的文件描述符...因此,您可以将整个读取操作移动到另一个线程中。因此,您的写入线程和处理线程将响应,即使读取 [select()] 线程处于休眠状态也是如此。

libsigc++ 的信号发射开销很小,因此我认为您可以将代码嵌入到读取线程本身中。 插槽可以存在于不同的线程中,这是您将接收信号的地方......

我认为Thrift源代码[完全基于boost]可能会引起您的兴趣,尽管Thrift不使用libsigc ++。

听起来好像你误解了选择; 选择(或轮询、epoll 等)的目的不是"等待数据",而是"等待一系列文件描述符或计时器或信号上发生的一个或多个事件"。

当您在选择呼叫中时,缺少哪些"响应能力"?你说它是一个控制台应用程序,所以你不是在谈论 GUI 循环,所以大概它与 IO 相关?如果是这样,那么您需要重构您的选择,以便等待您正在谈论的数据是一个元素;也就是说,如果您使用的是 select,则要等待输入的所有文件/套接字描述符(stdin 和 stdout 是文件描述符)的构建FD_SETs。

或者构建一个循环,定期调用"select",对任何挂起的输入进行较短的/test/超时,并且仅在选择告诉您有内容要读取时才尝试读取它。

听起来你有一个生产者-消费者风格问题。 有多种方法可以实现此问题的解决方案,但如今大多数人倾向于使用基于条件变量的方法(请参阅此基于 C++11 的示例)。

还有许多设计模式在实现时可以帮助缓解并发问题,例如:

半同步/半异步
  • 一种生产者-使用者样式模式,它在用事件填充队列的异步层和处理这些事件的同步层之间引入队列。
领导者/追随者
  • 多个线程轮流处理事件
  • 相关讨论可在此处获得。