createIoCompletionPort 函数 (ioapiset.h)

创建输入/输出 (I/O) 完成端口,并将其与指定的文件句柄相关联,或者创建尚未与文件句柄关联的 I/O 完成端口,以便在以后进行关联。

将打开的文件句柄的实例与 I/O 完成端口相关联,使进程能够接收涉及该文件句柄的异步 I/O 操作完成通知。

注意  

此处使用的术语“文件句柄”是指表示重叠 I/O 终结点的系统抽象,而不仅仅是磁盘上的文件。 任何支持重叠 I/O 的系统对象(例如网络终结点、TCP 套接字、命名管道和邮件槽)都可以用作文件句柄。 有关更多信息,请参阅“备注”部分。

 

语法

HANDLE CreateIoCompletionPort(
  [in]           HANDLE    FileHandle,
  [in, optional] HANDLE    ExistingCompletionPort,
  [in]           ULONG_PTR CompletionKey,
  [in]           DWORD     NumberOfConcurrentThreads
);

parameters

[in] FileHandle

打开的文件句柄或 INVALID_HANDLE_VALUE。

句柄必须是支持重叠 I/O 的对象。

如果提供了句柄,则必须为重叠的 I/O 完成打开它。 例如,在使用 CreateFile 函数获取句柄时,必须指定 FILE_FLAG_OVERLAPPED 标志。

如果指定了 INVALID_HANDLE_VALUE,则函数将创建 I/O 完成端口,而无需将其与文件句柄相关联。 在这种情况下,ExistingCompletionPort 参数必须为 NULL,并忽略 CompletionKey 参数。

[in, optional] ExistingCompletionPort

现有 I/O 完成端口的句柄,或 NULL。

如果此参数指定现有的 I/O 完成端口,则函数会将其与 FileHandle 参数指定的句柄相关联。 如果成功,函数将返回现有 I/O 完成端口的句柄;它不会创建新的 I/O 完成端口。

如果此参数为 NULL,则函数将创建新的 I/O 完成端口,如果 FileHandle 参数有效,则将其与新的 I/O 完成端口相关联。 否则不会发生文件句柄关联。 如果成功,函数会将句柄返回到新的 I/O 完成端口。

[in] CompletionKey

指定的文件句柄的每个 I/O 完成数据包中包含的每句柄用户定义完成键。 有关详细信息,请参见“备注”部分。

[in] NumberOfConcurrentThreads

操作系统允许并发处理 I/O 完成端口的 I/O 完成数据包的最大线程数。 如果 ExistingCompletionPort 参数不为 NULL,则忽略此参数。

如果此参数为零,则系统允许并发运行与系统中处理器数一样多的线程。

返回值

如果函数成功,则返回值是 I/O 完成端口的句柄:

  • 如果 ExistingCompletionPort 参数为 NULL,则返回值为新句柄。
  • 如果 ExistingCompletionPort 参数是有效的 I/O 完成端口句柄,则返回值为同一句柄。
  • 如果 FileHandle 参数是有效的句柄,则该文件句柄现在与返回的 I/O 完成端口相关联。
如果函数失败,则返回值为 NULL。 若要获得更多的错误信息,请调用 GetLastError 函数。

备注

可以指示 I/O 系统将 I/O 完成通知数据包发送到 I/O 完成端口,数据包将在这些端口上排队。 CreateIoCompletionPort 函数提供此功能。

I/O 完成端口及其句柄与创建它的进程相关联,并且不可以在进程之间共享。 但是,单个句柄可以在同一进程中的线程之间共享。

可以在三种不同的模式下使用 CreateIoCompletionPort:

  • 仅创建 I/O 完成端口,而不将其与文件句柄相关联。
  • 将现有 I/O 完成端口与文件句柄相关联。
  • 在单个调用中执行创建和关联。
若要创建 I/O 完成端口而不将其关联,请将 FileHandle 参数设置为 INVALID_HANDLE_VALUE,将 ExistingCompletionPort 参数设置为 NULL,将 CompletionKey 参数设置为零(在本例中将被忽略)。 将 NumberOfConcurrentThreads 参数设置为新 I/O 完成端口的所需并发值,或设置为默认值零(系统中的处理器数)。

FileHandle 参数中传递的句柄可以是支持重叠 I/O 的任何句柄。 通常,这是 CreateFile 函数使用 FILE_FLAG_OVERLAPPED 标志 (打开的句柄,例如文件、邮件槽和管道) 。 由其他函数(如 socket)创建的对象也可以与 I/O 完成端口相关联。 有关使用套接字的示例,请参阅 AcceptEx。 句柄只能与一个 I/O 完成端口相关联,在关联完成后,句柄将保持与该 I/O 完成端口的关联,直到该端口关闭。

有关 I/O 完成端口理论、用法和关联函数的详细信息,请参阅 I/O 完成端口

使用 ExistingCompletionPort 参数中的相同 I/O 完成端口句柄和 FileHandle 参数中的不同文件句柄多次调用 CreateIoCompletionPort,可以将多个文件句柄与单个 I/O 完成端口相关联。

使用 CompletionKey 参数可帮助应用程序跟踪哪些 I/O 操作已完成。 此值不由 CreateIoCompletionPort 用于功能控制;而是在与 I/O 完成端口关联时附加到 FileHandle 参数中指定的文件句柄。 对于每个文件句柄,此完成键应是唯一的,并且在整个内部完成队列过程中随文件句柄一起提供。 当完成数据包到达时,它会在 GetQueuedCompletionStatus 函数调用中返回。 PostQueuedCompletionStatus 函数也使用 CompletionKey 参数将你自己的特殊用途完成数据包排队。

打开句柄的实例与 I/O 完成端口关联后,无法在 ReadFileExWriteFileEx 函数中使用,因为这些函数具有自己的异步 I/O 机制。

最好不要使用句柄继承或 DuplicateHandle 函数调用来共享与 I/O 完成端口关联的文件句柄。 使用此类重复句柄执行的操作会生成完成通知。 建议仔细考虑此问题。

I/O 完成端口句柄以及与该特定 I/O 完成端口关联的每个文件句柄称为对 I/O 完成端口的引用。 当不再有对它的引用时,I/O 完成端口将被释放。 因此,必须正确关闭所有这些句柄以释放 I/O 完成端口及其关联的系统资源。 满足这些条件后,通过调用 CloseHandle 函数关闭 I/O 完成端口句柄。

在 Windows 8 和 Windows Server 2012 中,此函数由以下技术支持。

技术 支持
服务器消息块 (SMB) 3.0 协议
SMB 3.0 透明故障转移 (TFO)
具有横向扩展文件共享的 SMB 3.0 (SO)
群集共享卷文件系统 (CSV)
弹性文件系统 (ReFS)

要求

   
最低受支持的客户端 Windows XP [桌面应用 | UWP 应用]
最低受支持的服务器 Windows Server 2003 [桌面应用 | UWP 应用]
目标平台 Windows
标头 ioapiset.h (包括 Windows.h)
Library Kernel32.lib
DLL Kernel32.dll

另请参阅

AcceptEx

CreateFile

DuplicateHandle

文件管理函数

函数

GetQueuedCompletionStatus

GetQueuedCompletionStatusEx

I/O 完成端口

概述主题

PostQueuedCompletionStatus

ReadFileEx

使用 Windows 标头

Windows 套接字 2

WriteFileEx