相当于 Windows 上的 select for Pipes

use*_*423 2 c++ winapi pipe

我需要阻塞,直到我的管道之一有数据要读取。

我尝试过 WaitForMultipleObjects 但它只是立即返回说其中一个管道有数据。管道上的后续 ReadFile 会阻塞。

我无法使用 PeekNamedPipe,因为我需要阻塞直到数据可用,并且在带有睡眠的循环中进行查看会因睡眠而导致延迟反应。

这段代码是跨平台的,在 Linux 上一切都工作得很好,因为我可以在一组 fifo fd 上使用 Select,然后从 select 返回时准备好的那个中读取,但是在 Windows 上似乎没有任何等效的东西。

我看到很多人说你必须使用读/写的重叠操作,但这是否需要我循环并尝试读取每个管道?

是否没有任何单个阻塞操作会阻塞直到其中一个管道中有数据为止?

Rem*_*eau 5

我尝试过 WaitForMultipleObjects 但它只是立即返回说其中一个管道有数据。管道上的后续 ReadFile 会阻塞。

MSDN 的可等待对象类型列表中没有提到管道,因此您不能将管道传递给任何WaitFor...()函数系列。

我看到很多人说你必须使用读/写的重叠操作,但这是否需要我循环并尝试读取每个管道?

重叠 I/O 可以解决您的问题。

以重叠模式创建管道。然后您可以:

  1. 通过创建一个事件对象CreateEvent()并将其分配给OVERLAPPED用于给定读取操作的结构。ReadFile/Ex()然后,您可以在多个管道上发出异步操作,并WaitForMultipleObject()用于等待事件对象,直到其中之一收到信号。返回值WaitForMultipleObjects()将告诉您发出了哪个事件的信号,以及通过关联哪个管道已读取一些数据。

  2. 使用GetQueuedCompletionStatus/Ex()而不是WaitForMultipleObjects(),那么您可以省略事件对象。 GetQueuedCompletionStatus/Ex()将告诉您哪些特定OVERLAPPED结构已完成(hEvent如果需要,您可以使用该字段来传递用户定义的数据)。

MSDN 文档对此进行了介绍:

同步和重叠管道 I/O

select()可以在一次调用中报告多个已完成的操作。但是,WaitForMultipleObjects()和GetQueuedCompletionStatus()一次只能报告一个已完成的操作。您必须循环调用它们才能发现多个操作是否已完成。 GetQueuedCompletionStatusEx()另一方面,可以一次报告多个已完成的操作。

是否没有任何单个阻塞操作会阻塞直到其中一个管道中有数据为止?

是的。往上看。