OVERLAPPED Win32 结构中的 hEvent 成员
当使用异步I/O(或者Win32术语中的“重叠”I/O)时,我们需要处理OVERLAPPED
结构及其hEvent
成员。如果I/O函数会延迟读或写操作,我们将得到一个ERROR_IO_PENDING
错误代码,然后我们将使用WaitForXxxEvent
函数等待异步操作完成,然后我们将调用GetOverlappedResult
。
但是,如果 I/O 操作立即完成,我们将不会得到 ERROR_IO_PENDING
,并且在读取操作中,我们的读取缓冲区将立即被填充。但是 OVERLAPPED::hEvent 成员呢?会被设置为有信号状态吗?我还没有找到对此的明确说法。
这个问题可能看起来毫无意义(如果我知道操作已经完成,为什么要处理该事件?),但是我有一个模仿重叠模式的库,并且我需要具有相同的确切行为。
正如 edgar.holleis 在 他的评论,Raymond Chen在他的博客中解释了这一点: 链接
如果异步 I/O 同步完成,那么 OVERLAPPED 结构中的 hEvent 是否仍会发出信号?
是的。
当 I/O 完成时(无论是同步还是异步), 发出事件信号并排队完成状态通知。这
GetOverlappedResult/Ex
函数可用于等待 I/O 已经完成;它只会立即返回。如果你问 HasOverlappedIoCompleted I/O 是否已完成,以及 I/O 同步完成,它会正确报告,“是的,当然 完全的。哎呀,它很久以前就完成了!”换句话说,你可以逻辑地处理异步的情况 I/O 请求同步完成,就像已完成一样 异步地。它只是在您之前异步完成 眨眼。
When asynchronous I/O (or "overlapped" I/O in Win32 jargon) is used, we need to deal with the OVERLAPPED
structure and his hEvent
member. If the I/O function will delay the read or write operation, we will get an ERROR_IO_PENDING
error code, then we will wait the asynchronous operation to complete with a WaitForXxxEvent
function, then we will call GetOverlappedResult
.
However, if the I/O operation is immediately completed, we will not get ERROR_IO_PENDING
, and in a read operation our read buffer will be filled immediately. But what about the OVERLAPPED::hEvent
member? Will it be set to signaled state? I've not found a clear statement about that.
This question may seem pointless (why deal with the event if I know that the operation is already completed?), however I have a library that mimics the overlapped pattern and I need to have the same exact behavior.
As pointed by edgar.holleis in his comment, Raymond Chen explained this in his blog: Link
If an asynchronous I/O completes synchronously, is the hEvent in the OVERLAPPED structure signaled anyway?
Yes.
When an I/O completes (whether synchronously or asynchronously), the
event is signaled and completion status notifications are queued. TheGetOverlappedResult/Ex
function can be used to wait on an I/O that
has already completed; it will merely return immediately. If you ask
HasOverlappedIoCompleted whether the I/O has completed, and the I/O
completed synchronously, it will correctly report, "Yeah, of course it
completed. Heck, it completed a long time ago!"In other words, you can logically treat the case of an asynchronous
I/O request completing synchronously as if it had completed
asynchronously. It just completes asynchronously before you even
blinked.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不,不会。我花了很长时间才弄清楚这一点;)
No it won't. It took me ages to figure that one out the hard way ;)