python - IO完成端口 key 混淆

标签 python windows winsock ctypes iocp

我正在使用 ctypes 模块在 Python 中使用 Windows DLL API 编写基于 IO 完成端口的服务器 ( source code here )。但这是对 API 的非常直接的使用,这个问题是针对那些了解 IOCP 而不是 Python 的人。

据我了解 CreateIoCompletionPort 的文档,当您使用与创建的 IOCP 关联的文件句柄(在我的例子中是套接字)调用此函数时,您指定了“用户定义的”完成键。当您开始调用 GetQueuedCompletionStatus 时,您将获得一个完成键值以及一个指向重叠对象的指针。完成键应标识已完成的重叠对象和请求。

但是,假设我在带有重叠对象的 CreateIoCompletionPort 调用中传入 100 作为完成键。当相同的重叠对象完成其 IO 并通过 GetQueuedCompletionStatus 返回时,伴随它的完成键要大得多并且与原始值 100 没有任何相似之处。

我是不是误解了完成键的工作原理,还是我在上面链接的源代码中做错了?

最佳答案

我在日常实践中发现,最好只关注 OVERLAPPED 结果,因为它不会发生变化。您可以有效使用它的一种方法是使用如下内容:

struct CompletionHandler
{
    OVERLAPPED dummy_ovl;
    /* Stuff that actually means something to you here */
};

当您向 IOCP 发布内容时(无论是通过 I/O 调用还是仅通过 Win32 API 发布),您首先创建一个 CompletionHandler 对象,您将使用它来跟踪调用,并强制转换该对象的地址到 OVERLAPPED*

CompletionHander my_handler;
// Fill in whatever you need to in my_handler
// Don't forget to keep the original my_handler!

// I/O call goes here, and for OVERLAPPED* give: (OVERLAPPED*)&my_handler

这样,当您获得 OVERLAPPED 结果时,您所要做的就是将其转换回 CompletionHandler 瞧!您拥有通话的原始上下文。

OVERLAPPED* from_queued_completion_status;
// Actually get a value into from_queued_completion_status

CompletionHandler* handler_for_this_completion = (CompletionHandler*)from_queued_completion_status;
// Have fun!

有关真实世界设置的更多详细信息,请查看 Boost 的 ASIO for Windows 实现 (ver 1.42 header here)。有一些细节,例如验证您从 GetQueuedCompletionStatus 获得的 OVERLAPPED 指针,但同样,请参阅链接以了解实现的好方法。

关于python - IO完成端口 key 混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1176477/

相关文章:

python - 计算重复平均 python

Python 从 URL 读取页面?更好的文档?

node.js - 即使在 PATH 中也无法识别 Node

c - undefined reference /未解析的外部符号

c - Winsock 发送函数无限期等待

python - Pandas - 拆分、重构和重载 ID 列

python - 处理 Python 内存使用的可能修复

windows - 常见的 Windows 服务设计模式有哪些?

windows - 在 powershell 中创建一个包含字符串和列表的 HashMap ?

c++ - bind() 和 listen() 函数出错 (WinSock)