等同于Windows上的管道选择 [英] equivalent of select for pipes on windows

查看:92
本文介绍了等同于Windows上的管道选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要阻塞,直到我的管道之一要读取数据为止.

I need to block until one of my pipes has data to be read.

我尝试了WaitForMultipleObjects,但它立即返回,说其中一个管道具有数据.管道块上的后续ReadFile.

I have tried WaitForMultipleObjects but it just returns immediately saying that one of the pipes has data. A subsequent ReadFile on the pipe blocks.

我无法使用PeekNamedPipe,因为我需要在数据可用之前阻塞,而在带有睡眠的循环中偷看会由于睡眠而导致反应延迟.

I cannot use PeekNamedPipe because I need to block until data is available, and peeking in a loop with sleep would result in a delayed reaction because of the sleep.

这段代码是跨平台的,在Linux上一切正常,因为我可以在一组fifo fd上使用Select,然后在select返回时从准备就绪的那一组读取,但是似乎没有任何等效项.窗口.

This code is cross-platform and everything works great on linux because I can use Select on a set of fifo fd's and then read from the one that is ready when select returns, however there doesn't seem to be any equivalent on windows.

我见过很多人说您必须对读/写使用重叠的操作,但这难道不是我需要循环并尝试读取每个管道吗?

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?

难道没有一个阻塞操作会阻塞直到其中一个管道中有数据吗?

Is there no single blocking operation that will block till one of the pipes has data in it?

推荐答案

我尝试了WaitForMultipleObjects,但它立即返回,说其中一个管道具有数据.管道块上的后续ReadFile.

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...()函数族.

Pipes are not mentioned in MSDN's list of waitable object types, so you can't pass a pipe to any of the WaitFor...() family of functions.

我见过很多人说您必须对读/写使用重叠的操作,但这难道不是我需要循环并尝试读取每个管道吗?

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是解决问题的方法.

Overlapped I/O is the solution to your problem.

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

Create your pipes in overlapped mode. Then you can either:

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

  1. create an event object via CreateEvent() and assign it to the OVERLAPPED structure you use for a given read operation. Then you can issue asynchronous ReadFile/Ex() operations on multiple pipes and use WaitForMultipleObject() to wait on the event objects until one of them is signaled. The return value of WaitForMultipleObjects() will tell you which event was signaled, and by association which pipe has read some data.

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

use GetQueuedCompletionStatus/Ex() instead of WaitForMultipleObjects(), then you can omit the event objects. GetQueuedCompletionStatus/Ex() will tell you which specific OVERLAPPED struct(s) have been completed (you can use the hEvent field to pass around user-defined data, if desired).

MSDN文档中对此进行了介绍:

This is covered in the MSDN documentation:

同步和重叠管道I/O

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

select() can report multiple completed operations in a single call. However, WaitForMultipleObjects() and GetQueuedCompletionStatus() can only report a single completed operation at a time. You would have to call them in a loop to discover if multiple operations have completed. GetQueuedCompletionStatusEx(), on the other hand, can report multiple completed operations at one time.

难道没有一个阻塞操作会阻塞直到其中一个管道中有数据吗?

Is there no single blocking operation that will block till one of the pipes has data in it?

是的.见上文.

这篇关于等同于Windows上的管道选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆