我正在编写一个基于IO完成端口的服务器(source code here),使用Python中的windowsdllapi使用ctypes模块。但这是API的一个非常直接的用法,这个问题是针对那些了解IOCP而不是Python的人。在
根据我对CreateIoCompletionPort的文档的了解,当您使用与创建的IOCP关联的文件句柄(在我的例子中是套接字)调用此函数时,可以指定“用户定义的”完成键。当您开始调用GetQueuedCompletionStatus时,您将获得一个完成键值以及一个指向重叠对象的指针。完成键应该标识哪些重叠的对象和请求已经完成。在
但是,假设我在CreateIoCompletionPort调用中传入100作为一个重叠对象的完成键。当同一个重叠对象的IO已完成并通过GetQueuedCompletionStatus返回时,伴随它的完成键要大得多,与原始值100没有任何相似之处。在
我是不是误解了完成键的工作原理,还是我在上面链接的源代码中做得不对?在
GetQueuedCompletionStatus
返回两个东西,OVERLAPPED
结构和一个完成键。完成键表示每个设备的信息,OVERLAPPED
结构表示每次调用的信息。完成键应该与调用CreateIoCompletionPort
中给出的匹配。通常,您将使用指向包含有关连接信息的结构的指针作为完成键。在看起来您没有使用
completionKey
执行由GetQueuedCompletionStatus
返回的任何操作。在我猜你想:
编辑:
Python是否知道在
CreateAcceptSocket
中创建的OVERLAPPED
结构正被win32api异步使用并阻止它被GC'd?在我在日常实践中发现,最好只关注
OVERLAPPED
的结果,因为这不会改变。有效使用它的一种方法是使用如下内容:当您向IOCP发布内容时(无论是通过I/O调用还是仅仅通过win32api发布),首先创建一个用于跟踪调用的
^{2}$CompletionHandler
对象,并将该对象的地址强制转换为OVERLAPPED*
。在这样,当您得到
OVERLAPPED
结果时,您所要做的就是将它转换回CompletionHandler
然后瞧!你有你电话的原始背景。在有关实际设置的更多详细信息,请查看Boost的ASIO For Windows实现(ver 1.42 header here)。有一些细节,比如验证从
GetQueuedCompletionStatus
获得的OVERLAPPED
指针,但是同样,请参阅链接以获得实现的好方法。在您应该将完成键视为“按连接”数据,将(扩展)重叠结构视为“按i/o”操作。在
有些人将扩展重叠结构用于两者,并将所需的所有信息存储在扩展重叠结构中。我总是存储一个引用计数的对象,它将套接字包装在完成键中,并将引用计数的数据缓冲区作为扩展的重叠结构。如果你感兴趣,你可以看看some example IOCP code in C++ here。在
实际上,完成键只是一个不透明的数据句柄,当套接字完成时,I/O完成系统将返回给您。在
相关问题 更多 >
编程相关推荐