I/O 完成端口 C++ 和线程池

I/O Completion ports C++ And Threadpools

我试图了解哪个是真的,我在多个来源中读到 IOCP 可用于实现线程池,我在其线程中使用多个 IOCP 来进行进程间通信,我正在尝试重新实现我的代码以仅使用一个 IOCP 和一个线程池来管理我的所有进程。

我可以只使用一个线程并让 IOCP 自己的内部线程池管理异步 I/O 还是我必须使用线程池对象才能做到这一点?

编辑以澄清 IOCP 是否有自己的线程池,我所要做的就是 link 我对它的处理并让它管理异步 IO?还是我必须自己制作胎面?

MSDN文档对此不是很清楚。提前致谢

does the IOCP has it's own internal threadpool ?

没有。如果您自己创建 IOCP ( KQUEUE) - 您需要通过自己调用 GetQueuedCompletionStatus[Ex] (ZwRemoveIoCompletion[Ex] )。来自哪个线程 - 完全是你的 task.so 这里你需要自己创建一些“线程池”,它将从 IOCP 中弹出数据包并处理它。

如果您将系统 api 用于线程池 - 它在内部使用 IOCP 但您从不直接访问 IOCP - 甚至无法处理它。这一切都在系统上——创建 IOCP,创建线程池,监听 IOCP,调用回调。在这个方案中 - 你自己从 IOCP 弹出数据包 - 注册一些回调 - 当从 IOCP 弹出数据包时系统调用。

例如 - BindIoCompletionCallback

Associates the I/O completion port owned by the thread pool with the specified file handle.

注意 - I/O 线程池 拥有的完成端口,而不是 I/O 完成端口

拥有的线程池

但在此 api - 没有 IOcp 句柄作为参数。默认(因为这里没有办法指定另一个池)系统使用的线程池。它iocp。如果文件对象在这个 api 调用之后保存指向 iocp 的指针并且当 I/O 完成时 - 数据包将排队到这个 iocp,系统池弹出这个数据包并调用你的回调。

CreateThreadpoolIo - 做与 BindIoCompletionCallback 相同的事情 - 关联 I/O 拥有的完成端口具有指定文件句柄的线程池.

但这里写的不是最好的方式

Creates a new I/O completion object.

您可能认为新的 IOCP 是通过调用此 api 创建的。但不是。一些用户模式结构——是的,但不是新的 IOCP。 object != 端口在这里。 IOCP 每个线程池都是单一的,并且只创建一次。通过这个 api.

CreateThreadpool

Allocates a new pool of threads to execute callbacks.

并作为此任务的一部分 - 创建一个新的 I/O 完成端口。如此间接-通过创建新池-您创建了新的 IOCP(尽管永远无法直接访问它)。那么你需要:

To use the pool, you must associate the pool with a callback environment. To create the callback environment, call InitializeThreadpoolEnvironment. Then, call SetThreadpoolCallbackPool to associate the pool with the callback environment.

然后你可以将这个回调环境传递给 CreateThreadpoolIo 例如。这个 api 和更旧的 BindIoCompletionCallback 之间的主要区别 - 你可以在这里使用非默认线程池。然而,在大多数情况下,我认为 - 进程中只使用单个默认线程池。


所以一般来说 - 如果您自己创建 IOCP - 您需要自己管理它并创建专用线程,用于从 IOCP 弹出数据包 - 这就是所谓的“线程池”

或者您可以使用系统池。在这种情况下,您根本不会直接访问 IOCP。尽管这可能没有直接记录——每个线程池只存在一个 IOCP。如果您仅使用默认进程线程池 - 您也使用单个 IOCP。如果您创建额外的线程池 - 间接创建额外的 IOCP。

和 IOCP - 不自行创建任何线程。像事件对象 - 不创建线程,它将等待这个事件