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

从I / O完成端口中删除句柄以及有关IOCP的其他问题

CreateIoCompletionPort函数允许创build新的I / O完成端口,并将文件句柄注册到现有的I / O完成端口。

然后,我可以使用任何函数,例如套接字上的recv或具有OVERLAPPED结构的文件上的ReadFile来启动asynchronous操作。

我必须检查函数调用是否同步返回,尽pipe它是用OVERLAPPED结构调用的,在这种情况下直接处理它。 在另一种情况下,当返回ERROR_IO_PENDING时,我可以使用GetQueuedCompletionStatus函数在操作完成时得到通知

出现的问题是:

如何在Windows中提取目录属性

如何检查我在Windows上打开的文件

如何在Java中使文件search程序?

如何使用schell脚本从文件读取元素,做一些计算和回写?

查找没有指定字符的文件

如何从I / O完成端口中删除句柄? 例如,当我向IOCP添加套接字时,如何删除封闭的套接字? 我是否应该使用相同的完成键重新注册一个套接字?

另外,有没有办法让电话总是通过I / O完成端口,不要同步返回?

最后,有可能例如recvasynchronous,但同步send ? 例如,当实现一个简单的echo服务时:我可以用一个asynchronousrecv等待新数据,但以同步的方式send响应,以便减less代码复杂性? 就我而言,在处理第一个请求之前,我不会再进行第二次调用

如果已经请求了一个asynchronousReadFile ,但是在完成之前会发生一个WriteFile到同一个文件的处理。 ReadFile是否会被取消,并且一旦写入完成,我必须重新启动读取过程? 或者我必须在写入之前手动取消ReadFile ? 这个问题与通讯设备结合起来。 所以,如果同时发生,写入和读取不应该发生问题。

Linux上文件cpu使用情况

比较C ++中的两个文件

电子:定制协议示例在Windows中不起作用

写入后文件中的垃圾

在C#和Windows中编写交易文件

如何从I / O完成端口中删除句柄?

根据我的经验,您无法取消完成端口的句柄。 但是,可以通过设置OVERLAPPED结构的hEvent字段的低位来禁用完成端口通知:请参阅GetQueuedCompletionStatus的文档。

例如,当我向IOCP添加套接字时,如何删除封闭的套接字? 我是否应该使用相同的完成键重新注册一个套接字?

从I / O完成端口不需要显式地分离句柄; 关闭手柄就足够了。 您可以将多个句柄关联到相同的完成键; 找出哪个请求与I / O完成关联的最好方法是使用OVERLAPPED结构。 事实上,你甚至可能扩展OVERLAPPED来存储额外的数据。

另外,有没有办法让电话总是通过I / O完成端口,不要同步返回?

这是认行为,即使ReadFile / WriteFile返回TRUE 。 您必须显式调用SetFileCompletionNotificationModes来告诉Windows在返回TRUE和ERROR_SUCCESS时不排队完成数据包。

有可能例如recv异步,但同步send ?

不要使用recv和send ; 您需要使用接受OVERLAPPED结构的函数,如WSARecv , WSASend或者ReadFile和WriteFile 。 如果你的代码是用来处理多种类型的I / O句柄,比如套接字和命名管道,那么使用后者可能会更方便一些。 这些功能提供了一个同步模式,所以如果你使用它们,你可以混合使用异步和同步调用

如果已经请求了一个异步ReadFile,但是在它完成之前会发生一个WriteFile到同一个文件的处理呢?

没有隐含的取消。 只要你使用单独的OVERLAPPED结构来读/写全双工设备,我没有理由不能做并发I / O操作。

正如我已经指出的那样,人们普遍认为不可能从完成端口中删除句柄是错误的,这可能是由于我几乎找不到所有文档中的任何提示而导致的。 其实,这很简单:

使用FileinformationClass的FileReplaceCompletioninformation枚举器值和指向Fileinformation参数的FILE_COMPLETION_informatION结构的指针调用NtSetinformationFile 。 在这个结构中,将Port成员设置为NULL (或C ++中的nullptr ),将文件从当前连接的端口上解除关联(我猜如果没有连接到任何端口,什么都不会发生),或者将Port设置为一个有效的HANDLE到另一个完成端口来将文件与那个文件关联起来。

首先一些重要的更正。

如果重叠的I / O操作立即完成( ReadFile或类似的I / O函数返回成功) – I / O完成已经安排到IOCP。

此外,根据你的问题,我认为你在文件/套接字句柄和在它们上发出的特定I / O操作之间混淆。

现在,关于你的问题:

AFAIK没有传统的方法来从IOCP中删除文件/套接字句柄(通常你不必这样做)。 你说的是从IOCP中删除关闭的句柄,这是绝对不正确的。 你不能删除一个关闭的句柄,因为它不再引用一个有效的内核对象!

更正确的问题应该是如何正确关闭文件/套接字。 答案是:关闭你的手柄。 所有未完成的I / O操作(在这个句柄上发出)将很快返回一个错误代码(中止)。 然后,在完成例程(在循环中调用GetQueuedCompletionStatus例程)应该执行每个I / O所需的清理。

正如我已经说过的,所有I / O完成都在同步和异步情况下到达IOCP。 唯一没有到达IOCP的情况是当一个I / O同时完成一个错误 。 无论如何,如果你想要一个统一的处理 – 在这种情况下,你可以发布人工完成数据到IOCP(使用PostQueuedCompletionStatus )。

您应该使用WSASend和WSARecv (不recv和send )重叠的I / O。 不过,即使套接字已经打开了WSA_FLAG_OVERLAPPED标志 – 你可以调用I / O函数而不指定OVERLAPPED结构。 在这种情况下,这些功能同步工作。 这样你可以决定每个函数调用的同步/异步模式。

混合重叠的读/写请求没有问题。 唯一微妙的一点是,如果您尝试从当前正在写入的文件位置读取数据,会发生什么情况。 其结果可能依赖于微妙的东西,例如硬件完成I / O的顺序,一些PC定时参数等。这种情况应该避免。

如何从I / O完成端口中删除句柄? 例如,当我向IOCP添加套接字时,如何删除封闭的套接字? 我是否应该使用相同的完成键重新注册一个套接字?

你有错误方法。 设置文件对象使用的I / O完成端口 – 当文件对象被删除时,您无需担心。 你感到困惑的原因是因为Win32暴露了底层本地API的功能( CreateIoCompletionPort在一个函数中做了两个完全不同的事情)。

另外,有没有办法让电话总是通过I / O完成端口,不要同步返回?

这是一直如此。 只有从Windows Vista开始,才能自定义完成通知的处理方式。

如果已经请求了一个异步ReadFile,但是在完成之前会发生一个WriteFile到同一个文件的处理。 ReadFile是否会被取消,并且一旦写入完成,我必须重新启动读取过程?

Windows中的I / O操作本质上是异步的,并且请求总是排队的。 您可能不认为这是因为您必须在CreateFile指定FILE_FLAG_OVERLAPPED来打开异步I / O。 然而,在本地层,同步I / O实际上是一个附加的,便利的事情,内核跟踪你的文件位置,并在返回之前等待I / O完成。

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

相关推荐