gpt4 book ai didi

c++ - SetFileCompletionNotificationModes 似乎无法正常工作

转载 作者:行者123 更新时间:2023-11-30 02:47:38 25 4
gpt4 key购买 nike

我正在使用 SetFileCompletionNotificationModes() API 来优化我的 I/O 完成端口循环,但它似乎无法正常工作。即使我为套接字和句柄设置了 FILE_SKIP_COMPLETION_PORT_ON_SUCCESS,如果 ReadFile() WriteFile() WSARecv() WSASend() 返回同步

我确信 MSDN 所说的 3 个条件必须为真(完成端口与文件句柄关联,文件为异步 I/O 打开,请求立即返回成功而不返回 ERROR_PENDING),并且都是真的,那么为什么我仍然收到 I/O 完成调用?

当我调用 SetFileCompletionNotificationModes() 时,它返回成功,因此没有任何错误,系统是 Windows 7。

当我在我的套接字/句柄上激活 SetFileCompletionNotificationModes() 后,我如何可以复制一个场景,我可以清楚地看到 I/O 完成回调不会被调用?

我猜是在socket上写几个字节的时候发生的,因为socket的缓冲区比较大,我没有填满,所以再写几个字节应该不会阻塞,因为还有很多缓冲区中的空间,所以它应该立即返回,但不是 ERROR_IO_PENDING,只是以同步方式,对吧? (或多或少,以类似 unix EWOULDBLOCK/EAGAIN 的方式:当我调用 write() 几个字节时,它立即返回,并且不返回 EAGAIN,因为写入中仍有空间缓冲区)。

它不会那样做。即使在套接字上多次写入几个字节,它仍然会调用 I/O 完成回调,避免设置 FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 的好处

我错过了什么重要的东西吗?有什么线索吗?

注意:我知道如果套接字仅与返回可安装文件系统 (IFS) 句柄的分层服务提供程序 (LSP) 兼容,这将无法工作,但我的情况并非如此,它应该可以工作。顺便说一句,我也在尝试使用管道和文件。

文件不应该永远不会调用 I/O 完成回调,因为它们永远不会阻塞,就像在 unix 中 read()write() 对本地文件的调用永远不会返回EWOULDBLOCK/EAGAIN,所以带有 FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 句柄的 ReadFile()WriteFile() 应该立即返回?

最佳答案

仅当网络堆栈不再需要您提供的数据缓冲区时,才会生成网络写入完成。很难推断什么时候会这样,而且它也有点无关紧要,不用担心。当您发出带有 FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 设置的重叠写入时,当且仅当完成同步发生时,您的写入操作才会返回 0。编写代码来正确处理这种情况(它与 recv 端所需的代码相同)并忘记它。在可能的情况下,您将获得性能和上下文切换优势,而在不可能的情况下,您的代码也能正常工作。

至于文件系统访问,这取决于文件系统驱动程序,可能还取决于实际硬件。参见 here获取有关让某些硬件完全执行异步文件写入有多难的信息。然后请注意,当我将我在那里谈论的测试从具有“普通”SATA 磁盘的工作站切换到具有硬件 raid 的服务器时,一切都不同了,所有的写入总是完全异步的......

关于c++ - SetFileCompletionNotificationModes 似乎无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22617539/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com