c++ - 相当于 Windows 上的 select for Pipes

标签 c++ winapi pipe

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

我尝试过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 可以解决您的问题。

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

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

  2. 使用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/

相关文章:

c++ - "const method"读取成员变量时编译错误

c - 新创建的用户上的 RegOpenCurrentUser(KEY_WRITE)

python - 打开从 os.listdir() 找到的文件并对文件执行任务

swift - 如何在 Swift 中获得 `Pipe` 到标准输入/输出/错误?

c# - C++ 客户端,C# 服务器

C++ 运算符重载输入运算符 >> 以类外的对象作为成员

c++ - GUID 解释 - C++

c - 使用 C 从 Windows 注册表读取

javascript - 从 Web 浏览器进行 Win API 调用?

c - 在 C 编程中使用管道