微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

GetOverlappedResultEx 将创建一个线程来处理还是我必须创建和同步线程?

如何解决GetOverlappedResultEx 将创建一个线程来处理还是我必须创建和同步线程?

试图了解这是如何工作的...我是否必须创建各种线程来利用 GetoverlappedResultEx 的功能?但是,为什么我不能将 GetoverlappedResult 放在与主线程不同的线程中来处理 IO 的阻塞而不干扰主操作?

GetoverlappedResult 函数

https://docs.microsoft.com/en-us/windows/win32/api/ioapiset/nf-ioapiset-getoverlappedresult

检索对指定文件、命名管道或通信设备的重叠操作的结果。要指定超时间隔或等待可警报线程,请使用 GetoverlappedResultEx。

https://docs.microsoft.com/en-us/windows/win32/api/ioapiset/nf-ioapiset-getoverlappedresultex

在指定的超时间隔内检索对指定文件、命名管道或通信设备的重叠操作的结果。调用线程可以执行警报等待。

https://docs.microsoft.com/en-us/windows/win32/fileio/alertable-i-o

解决方法

您自己处理线程以实现并发性。

基本上有三种方法:

  1. 启动重叠(即异步完成)I/O 操作后,您会执行其他操作,然后每隔一段时间轮询句柄以查看重叠操作是否已完成。这是您如何使用 GetOverlappedResult 查找 STATUS_PENDING 来查看操作是否尚未完成。

  2. 您坐在那里等待重叠的操作完成。但这并没有那么糟糕,因为您实际上可以坐在那里等待一组重叠操作中的任何一个完成。任何一个完成你处理它,然后循环等待其余的。当然,处理它可能会触发另一个异步操作,您可以将该句柄添加到列表中。这是您使用 WaitForSingleObject{Ex} 或更好的 WaitForMultipleObjects{Ex} 的地方。

  3. 您使用 I/O 完成端口。在这里,您将一些句柄传递给称为 I/O 完成端口的内核对象 - 这个内核对象巧妙地将线程池(它自己管理)与回调结合在一起。这是同时处理多个(实际上是非常多)异步操作的非常有效的方法。在这些回调中,您可以做任何想做的事情,包括启动更多异步操作并将它们添加到同一个 I/O 完成端口。

还有第四个概念:alertable I/O,它在启动 I/O 的线程上的“APC”上执行回调,前提是您的线程处于“alertable”状态 - 这意味着它正在执行在内核中等待的某些 API 中的一个或另一个。但是我从来没有使用过它,因为它似乎有缺点(例如只在启动 I/O 的线程上工作,并且回调环境运行的环境不像它可能的那样清晰)并且如果您只需找出 I/O 完成端口并使用它们即可。

选项 #2 和 #3 当然涉及并发编程 - 因此在这两种情况下,您都必须确保您的回调相对于其他线程是线程安全的。

在插管上有很多关于所有这些方法的例子。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。