I/O Completion ports C++ And Threadpools

I'm trying to understand which is true, i read in multiple sources that IOCPs can be used to implement a threadpool, i'm using multiple IOCPs each in it's thread to do interprocess communication and i'm trying to reimplement my code to use just one IOCP and a threadpool to manage all my processes.

can i use just one thread and let the IOCP's own internal threadpool manage the asynchronous I/O or do i have to use a Threadpool object to so ?

edit to clarify do the IOCP has it's own threadpool and all i have to do is link my handles to it and let it manage the asynchronous IO ? or do i have to create the treads myself ?

the MSDN documentation is not very clear about this. thanks in advance


does the IOCP has it's own internal threadpool ?

no. if you create IOCP ( KQUEUE) by self - you need by self call GetQueuedCompletionStatus[Ex] (ZwRemoveIoCompletion[Ex] ). from which thread(s) - completelly your task.so here you need yourself create some "thread pool" which will be pop packets from IOCP and handle it.

if you use system api for thread pool(s) - it internal use IOCP but you never direct access IOCP - even can not got it handle. here all on system - create IOCP, create thread pool, listen on IOCP, call you callbacks. in this scheme - you instead pop packets from IOCP youself - register some callbacks - which system called when pop packet from IOCP.

for instance - BindIoCompletionCallback

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

note - I/O completion port owned by the thread pool, but not thread pool owned by the I/O completion port

but in this api - no IOcp handle as parameter. default (because no way here specify another pool) system thread pool used. and it iocp. if file object saved pointer to iocp after this api call and when I/O completed - packet will be queued to this iocp, system pool pop this packet and call your callback.

or CreateThreadpoolIo - do the same thing as BindIoCompletionCallback - Associates the I/O completion port owned by the thread pool with the specified file handle.

but here written in the not the best way

Creates a new I/O completion object.

you may think that new IOCP is created by call this api. but no. some user mode structure - yes, but not new IOCP. object != port here. IOCP is single per thread pool and created only once. by this api.

CreateThreadpool

Allocates a new pool of threads to execute callbacks.

and as part of this task - Creates a new I/O completion port. so indirect - by create new pool - you create new IOCP (despite never have direct access to it). then you need:

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.

and then you can pass this callback environment to CreateThreadpoolIo for instance. so main different between this api and more old BindIoCompletionCallback - you can use not default thread pool here. however in most case i think - only single, default, thread pool used in process.


so in general - if you create IOCP by self - you by self and need manage it and create dedicated threads, for pop packets from IOCP - this is and called "thread pool"

or you can use system pools. in this case you never direct access IOCP at all. despite this is may be not direct documented - exist exactly single IOCP per thread pool. if you use default only process thread pool - you use and single IOCP too. if you create aditional thread pool - indirect you create additional IOCP.

and IOCP - not create any threads by self. like event object - not create threads, which will be wait on this event