是否可以更改与 Windows I/O 完成端口中的 HANDLE 关联的 ULONG_PTR 完成键?

Posted

技术标签:

【中文标题】是否可以更改与 Windows I/O 完成端口中的 HANDLE 关联的 ULONG_PTR 完成键?【英文标题】:Is it possible to change the ULONG_PTR completion key associated to an HANDLE in Windows I/O Completion Ports? 【发布时间】:2013-10-05 10:50:50 【问题描述】:

我将使用 CreateNamedPipe() 创建的 HANDLE“h_server”与 I/O 完成端口相关联,并且 对于完成键,我使用函数指针:namedpipe_server_completion_routine()。

现在,当命名管道客户端连接请求触发时,句柄“h_server”成为客户端端点 在命名管道服务器应用程序中,所以我应该将其 I/O 完成键更改为另一种例程指针,完成 I/O、读取、写入等操作的 io_arrival_completion_routine(),这与命名管道服务器完成不同例行公事。

我想用那个 HANDLE 上的新完成键再次调用 CreateIoCompletionPort(),但它似乎不起作用,所以有办法改变那个键吗?也许有一些关于 DuplicateHandle 的 hack 之类的?

如果没有,我该如何解决?

注意:这个问题只存在于命名管道服务器,因为 AcceptEx() 以不同的方式工作:对于 tcp 服务器,当连接到达时,您基本上会在服务器上为客户端端点获得一个新 HANDLE,所以您可以将该 new HANDLE 与 io 完成端口和正确的完成键关联为正确的 io_arrival_completion_routine(),而与 tcp_server_completion_routine() 关联的 tcp 服务器的 HANDLE 将保持正确,并且其唯一作用将监听新的连接。

【问题讨论】:

CreateIoCompletionPort() 用它的第二个参数明确地支持这个场景。没有人可以看到你使用它,需要一个代码 sn-p。 这正是我用来将 HANDLE 关联到带有完成键的完成端口的方法。现在我的问题是更改 HANDLE 的完成键... 【参考方案1】:

将完成键从指向函数的指针更改为指向数据块的指针。然后,此数据块可以包含您需要的任何状态信息。

在最简单的情况下,数据块将只包含您当前尝试用作完成键的函数指针。

【讨论】:

谢谢。是的,这就是我现在采用的解决方案。我也想过完全忽略完成键,并使用我从 OVERLAPPED 派生的结构来设置回调指针,所以我可以在每次请求时更改它。

以上是关于是否可以更改与 Windows I/O 完成端口中的 HANDLE 关联的 ULONG_PTR 完成键?的主要内容,如果未能解决你的问题,请参考以下文章

Windows内核原理-同步IO与异步IO

I/O 完成端口可以帮助数据库而不是文件写入吗?

测试 I/O 完成端口支持

检测命名管道与 I/O 完成断开连接

I/O

Linux 和 I/O 完成端口?