SetFileCompletionNotificationModes似乎不能正常工作 [英] SetFileCompletionNotificationModes seems to not work properly

查看:219
本文介绍了SetFileCompletionNotificationModes似乎不能正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 SetFileCompletionNotificationModes() API来优化我的I / O完成端口循环,但似乎无法正常工作。
即使我为套接字和HANDLE设置FILE_SKIP_COMPLETION_PORT_ON_SUCCESS,如果 ReadFile() WriteFile(),I / O端口的完成回调仍然被调用。 ) WSARecv() WSASend() do return synchronosly

I'm using SetFileCompletionNotificationModes() API to optimize my I/O completion ports loops, but it seems to not work properly. Even if I set FILE_SKIP_COMPLETION_PORT_ON_SUCCESS for sockets and HANDLEs, an I/O port's completion callback is still called also if ReadFile() WriteFile() WSARecv() WSASend() do return synchronosly.

我确定MSDN所说的3个条件必须为真(完成端口与文件句柄相关联,该文件为异步I / O打开

I'm sure that the 3 conditions that MSDN says must be true (A completion port is associated with the file handle, The file is opened for asynchronous I/O, A request returns success immediately without returning ERROR_PENDING) are met, and are all true, so why I still receive I/O completion calls?

当我调用<$ c时,请求会立即返回成功而不返回ERROR_PENDING)都是真的,为什么我仍然收到I / O完成调用? $ c> SetFileCompletionNotificationModes()它返回成功,所以没有错误,无论什么,系统是Windows 7。

When i call SetFileCompletionNotificationModes() it returns success, so no errors or whatsoever, and the system is Windows 7.

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

How I can replicate a scenario when after I have activated SetFileCompletionNotificationModes() on my socket/HANDLEs, I can clearly see that the I/O completion callback won't be called?

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

I guessed that it happens when I write few bytes on a socket, since the socket's buffer is quite bigger, I didn't full it, so another write of another few bytes shouldn't block, since there are still a lot of room in the buffer, so it should return immediately, but not with ERROR_IO_PENDING, just in a synchronous way, right? (more or less, in a similar way of unix EWOULDBLOCK/EAGAIN: when i call write() for few bytes it returns immediately, and doesn't return EAGAIN, because there is still space in the write buffer).

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

Well it doesn't do that. Even for writing multiple times few bytes on a socket, it still calls the I/O completion callback, avoding the benefits of setting FILE_SKIP_COMPLETION_PORT_ON_SUCCESS

我缺少一些重要的东西吗?关于这一点的任何线索?

Am I missing something important? Any clue about that?

注意:我知道这不会工作,如果套接字只兼容分层服务提供商(LSP)返回可安装文件系统,但这不是我的情况,它应该工作。
Btw我也尝试这也管道和文件。

NOTE: I know that this wont work if the socket is only compatible with Layered Service Providers (LSP) that return Installable File Systems (IFS) handles, but that's not my case, it should work. Btw I'm trying this also with pipes and files.

不应该从来没有文件调用I / O完成回调,因为他们从来不阻止,就像在unix read() write()调用本地文件不会返回EWOULDBLOCK / EAGAIN,因此 ReadFile() WriteFile()与一个设置为FILE_SKIP_COMPLETION_PORT_ON_SUCCESS的句柄应该立即返回吗?

Shouldn't files never call I/O completion callbacks because they never block, just like in unix read() and write() calls on local files never returns EWOULDBLOCK/EAGAIN, so ReadFile() and WriteFile() with an handle set with FILE_SKIP_COMPLETION_PORT_ON_SUCCESS should return immediately?

推荐答案

仅当您提供的数据缓冲区不再需要网络堆栈时,才会生成网络写入完成。这有点难以推断,当这将是,它也有点不相关,不是担心的事情。当您使用 FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 设置发出重叠写入时,如果且仅当完成同步发生,您的写入操作将返回0。编写代码以正确处理该案例(它与recv端需要的代码相同),并忘记它。

A network write completion is only generated when the data buffer that you have provided is no longer required by the network stack. It's somewhat hard to reason about when this will be and it's also somewhat irrelevant and not something to worry about. When you issue an overlapped write with FILE_SKIP_COMPLETION_PORT_ON_SUCCESS set then your write operation will return 0 if and only if the completion has occurred synchronously. Write code to handle that case correctly (it's the same code that you need for the recv side) and forget about it. You'll get the performance and context switching advantages when it's possible and your code with work correctly when it isn't.

对于文件系统访问,这取决于文件系统访问文件系统驱动程序和可能的实际硬件。请参见此处一些信息,有多困难,可以得到一些硬件做异步文件写,永远。然后注意,当我切换测试,我谈到那里从具有'正常'SATA磁盘的工作站到具有硬件RAID的服务器一切都是不同的,所有的写入总是完全异步...

As for file system access, that depends on the file system drivers and, likely the actual hardware. See here for some information about how hard it can be to get some hardware to do async file writes at all, ever. Then note that when I switched the test that I talk about there from a workstation with 'normal' SATA disks to a server with hardware raid everything was different and all of the writes were always fully async...

这篇关于SetFileCompletionNotificationModes似乎不能正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆