【发布时间】:2016-07-09 00:39:57
【问题描述】:
我需要阻塞直到我的一个管道有数据要读取。
我已经尝试过 WaitForMultipleObjects 但它只是立即返回说其中一个管道有数据。管道块上的后续 ReadFile。
我不能使用 PeekNamedPipe,因为我需要阻塞直到数据可用,并且在睡眠循环中窥视会因为睡眠而导致延迟反应。
此代码是跨平台的,并且在 linux 上一切正常,因为我可以在一组 fifo fd 上使用 Select,然后在 select 返回时从准备好的那个中读取,但是似乎没有任何等效的窗户。
我看到很多人说你必须在读/写时使用重叠操作,但这不是需要我循环并尝试读取每个管道吗?
是否没有单个阻塞操作会阻塞直到其中一个管道中有数据?
【问题讨论】:
-
“我已经尝试过 WaitForMultipleObjects” - 如果您认为您为解决您的问题而编写的代码是相关的,那么您是对的。它属于问题,被简化为最小但理想的完整示例,尽可能重现您的问题。据我们所知,您错误地使用了 WaitForMultipleObjects,并且没有发布任何代码来反驳该假设。是的,重叠或 iocp 是我可能会这样做的方式。
-
@EJP 天哪! 1993年不是火发明之前吗?
-
更严肃的一点是:
WaitForSingleObject返回WAIT_OBJECT_0 + n,其中n是发出信号的数组索引的索引。我的猜测是因为文档中明确说明了这一点,您实际上并没有检查返回值,而对WaitForSingleObject的调用实际上是返回WAIT_FAILED。 (当然,这在业务中被称为有根据的猜测,因为您没有向我们展示您实际在做什么。您可能编写了正确检查返回值并出色处理错误的代码。)跨度> -
我现在无法发布代码,因为它正在工作,我现在回家了,尽管我确实正确处理了返回值,因为这就是我确定发出信号的句柄的方式。问题是 WaitForMultipleObjects 在管道中没有任何内容时立即返回。 MSDN 状态:“请注意,WAIT_OBJECT_0 定义为 0”。之后执行的代码是 (rv - WAIT_OBJECT_0) == 0 的结果,所以从我看到的情况来看,它向我发出信号表明第 0 个句柄已准备好 - 然后随后的 ReadFile 被阻止。
-
如果您阅读了
WaitForMultipleObjects()的文档,管道不是支持它等待的对象类型。确保返回值实际上在WAIT_OBJECT_0-WAIT_OBJECT_0+n的范围内,然后再减去WAIT_OBJECT_0得到索引。