我需要阻塞,直到我的管道之一有数据要读取。
我尝试过WaitForMultipleObjects,但它只是立即返回,表示其中一个管道有数据。管道上的后续 ReadFile 会阻塞。
我无法使用 PeekNamedPipe,因为我需要阻塞直到数据可用,并且在带有 sleep 的循环中进行查看会因 sleep 而导致延迟 react 。
这段代码是跨平台的,在 Linux 上一切都很好,因为我可以在一组 fifo fd 上使用 Select,然后从 select 返回时准备好的那个中读取,但是似乎没有任何等效的东西窗口。
我看到很多人说你必须使用读/写的重叠操作,但这是否需要我循环并尝试读取每个管道?
是否没有单一的阻塞操作会阻塞直到其中一个管道中有数据为止?
最佳答案
I have tried WaitForMultipleObjects but it just returns immediately saying that one of the pipes has data. A subsequent ReadFile on the pipe blocks.
MSDN 的可等待对象类型列表中未提及管道,因此您无法将管道传递给任何 WaitFor...()
系列函数。
I have seen many people saying you have to use overlapped operations with read/writes, but wouldn't this then require me to loop and try and read every single pipe?
重叠 I/O 可以解决您的问题。
以重叠模式创建管道。然后您可以:
通过
CreateEvent()
创建一个事件对象,并将其分配给用于给定读取操作的OVERLAPPED
结构。然后,您可以在多个管道上发出异步ReadFile/Ex()
操作,并使用WaitForMultipleObject()
等待事件对象,直到其中之一收到信号。WaitForMultipleObjects()
的返回值将告诉您哪个事件已发出信号,以及通过关联哪个管道已读取一些数据。使用
GetQueuedCompletionStatus/Ex()
而不是WaitForMultipleObjects()
,那么您可以省略事件对象。GetQueuedCompletionStatus/Ex()
将告诉您哪些特定的OVERLAPPED
结构已完成(您可以使用hEvent
字段来传递用户- 定义数据(如果需要)。
MSDN 文档对此进行了介绍:
Synchronous and Overlapped Pipe I/O
select()
可以在一次调用中报告多个已完成的操作。但是,WaitForMultipleObjects()
和 GetQueuedCompletionStatus()
一次只能报告一个已完成的操作。您必须循环调用它们才能发现多个操作是否已完成。另一方面,GetQueuedCompletionStatusEx()
可以一次报告多个已完成的操作。
Is there no single blocking operation that will block till one of the pipes has data in it?
是的。见上文。
关于c++ - 相当于 Windows 上的 select for Pipes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38277148/