CreateIoCompletionPort
函数允许创建新的 I/O 完成端口并将文件句柄注册到现有的 I/O 完成端口。
然后,我可以使用任何函数,例如套接字上的 recv
或具有 OVERLAPPED
结构的文件上的 ReadFile
来启动一个异步操作。
我必须检查函数调用是否同步返回,尽管它是用 OVERLAPPED
结构调用的,在这种情况下直接处理它。在另一种情况下,当返回 ERROR_IO_PENDING
时,我可以使用 GetQueuedCompletionStatus
操作完成时得到通知的函数。
出现的问题是:
如何从 I/O 完成端口删除句柄?例如,当我向 IOCP 添加套接字时,如何删除已关闭的套接字?我是否应该使用相同的完成 key 重新注册另一个套接字?
另外,有没有办法让调用始终通过 I/O 完成端口并且不同步返回?
最后,是否有可能以异步方式
recv
而以同步方式send
?例如,当实现一个简单的 echo 服务时:我可以使用异步recv
等待新数据,但以同步方式send
响应,从而降低代码复杂性吗?就我而言,无论如何,在处理第一个请求之前,我不会第二次recv
。如果已请求异步
ReadFile
,但在它完成之前,应该处理对同一文件的WriteFile
,会发生什么情况。ReadFile
是否会因错误消息而被取消,并且我必须在写入完成后立即重新启动读取过程?或者我必须在写入之前手动取消ReadFile
吗?这个问题与通信设备结合使用;因此,写入和读取如果同时发生应该不会出现问题。
最佳答案
How can I remove a handle from the I/O completion port?
根据我的经验,您无法解除句柄与完成端口的关联。但是,您可以通过设置 OVERLAPPED
结构的 hEvent
字段的低位来禁用完成端口通知:请参阅 GetQueuedCompletionStatus 的文档。 .
For example, when I add sockets to the IOCP, how can I remove closed ones? Should I just re-register another socket with the same completion key?
没有必要显式地解除句柄与 I/O 完成端口的关联;关闭 handle 就足够了。您可以将多个句柄与同一个完成键相关联;确定哪个请求与 I/O 完成相关联的最佳方法是使用 OVERLAPPED
结构。事实上,你甚至可以extend OVERLAPPED
存储额外的数据。
Also, is there a way to make the calls ALWAYS go over the I/O completion port and don't return synchronously?
这是默认行为,即使 ReadFile
/WriteFile
返回 TRUE
。您必须显式调用 SetFileCompletionNotificationModes告诉 Windows 在返回 TRUE
和 ERROR_SUCCESS
时不要排队完成数据包。
is it possible for example to
recv
asynchronously but tosend
synchronously?
不是通过使用recv
和send
;您需要使用接受 OVERLAPPED
结构的函数,例如 WSARecv
, WSASend
,或者 ReadFile
和 WriteFile
.如果您的代码旨在处理多种类型的 I/O 句柄,例如套接字和命名管道,那么使用后者可能更方便。这些函数提供同步模式,因此如果您使用它们,您可以混合使用异步和同步调用。
What happens if an asynchronous ReadFile has been requested, but before it completes, a WriteFile to the same file should be processed?
没有隐式取消。只要您对全双工设备的每次读/写都使用单独的 OVERLAPPED
结构,我看不出您不能执行并发 I/O 操作的原因。
关于c - 从 I/O 完成端口中删除句柄以及有关 IOCP 的其他问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6573218/