1

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

我需要提出具有 libsigc++ 信号的 C++ 类,当设备提供数据时会触发这些信号。

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

4

3 回答 3

0

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

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

或者构建一个循环,周期性地调用“select”,对 /test/ 任何待处理的输入有一个短暂的超时,并且只有在 select 告诉你有东西要读时才尝试读取它。

于 2013-05-20T20:13:53.777 回答
0

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

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

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

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

于 2012-10-07T11:54:12.860 回答
0

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

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

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