OVERLAPPED Win32 结构中的 hEvent 成员
Posted
技术标签:
【中文标题】OVERLAPPED Win32 结构中的 hEvent 成员【英文标题】:hEvent member in OVERLAPPED Win32 structure 【发布时间】:2010-03-24 21:54:34 【问题描述】:当使用异步 I/O(或 Win32 术语中的“重叠”I/O)时,我们需要处理OVERLAPPED
结构和他的hEvent
成员。如果 I/O 函数会延迟读或写操作,我们会得到一个ERROR_IO_PENDING
错误代码,然后我们会用一个WaitForXxxEvent
函数等待异步操作完成,然后我们会调用GetOverlappedResult
。
但是,如果 I/O 操作立即完成,我们将不会得到ERROR_IO_PENDING
,并且在读取操作中,我们的读取缓冲区将立即被填满。但是OVERLAPPED::hEvent
成员呢?它会被设置为信号状态吗?我还没有找到明确的说法。
这个问题可能看起来毫无意义(如果我知道操作已经完成,为什么还要处理该事件?),但是我有一个模仿重叠模式的库,我需要具有相同的确切行为。
正如edgar.holleis 在his comment 中指出的那样,Raymond Chen 在他的博客中对此进行了解释:http://blogs.msdn.com/b/oldnewthing/archive/2014/02/06/10497096.aspx
如果异步 I/O 同步完成,OVERLAPPED 结构中的 hEvent 是否仍会发出信号?
是的。
当 I/O 完成时(无论是同步还是异步), 事件发出信号,完成状态通知排队。这
GetOverlappedResult/Ex
函数可用于等待 I/O 已经完成;它只会立即返回。如果你问 HasOverlappedIoCompleted I/O 是否已经完成,以及 I/O 同步完成,它会正确报告,“是的,当然它 完全的。哎呀,很久以前就完成了!”换句话说,您可以在逻辑上处理异步的情况 I/O 请求同步完成,就好像它已经完成一样 异步。它甚至在您之前异步完成 眨了眨眼。
【问题讨论】:
如果操作立即完成,该事件也会发出信号。它在 Windows 7 中使用命名管道进行了测试。 【参考方案1】:不,不会的。我花了很长时间才弄清楚这一点;)
【讨论】:
这违反直觉...文档说接受 OVERLAPPED 的 I/O 函数将始终重置事件(因此我们不必在调用之前手动重置它),并且将在 I/O 操作完成时发出事件信号。现在,如果 I/O 操作立即完成,则应在 I/O 函数返回 TRUE 时发出事件信号...嗯... 我不会说它把我搞糊涂了,但我在 hEvent 方面遇到了重大问题。最后,我将其解雇并使用了“WaitForIOCompletion”函数,该函数会一直休眠直到完成。 @edgar.holleis 谢谢,您应该将此添加为完整答案以上是关于OVERLAPPED Win32 结构中的 hEvent 成员的主要内容,如果未能解决你的问题,请参考以下文章
OVERLAPPED结构与GetOverlappedResult函数