Async I/O and I/O completion ports

These days, the testers in Indigo are working on their TDSs (test design specifications). I own testing an area for which I needed to read up PostQueuedCompletionStatus; which lead to reading about async I/O and I/O completion ports. Pretty interesting stuff. And anytime I explain what I understood, I find that it stays with me longer! Now that I am blogging, this is an excellent place to try and relate some of the key points.

For those of you who have used the CLR thread pool know thats its recommended to be used for short-lived work items. For I/O intensive situations, the CLR thread pool doesnt have native support (there are Win32 APIs that let you use the I/O completion ports).

I/O completion ports are the way in which an app uses a pool of threads to process asynchronous I/O requests. These threads are kernel threads and their only job in life is to process I/O requests. Applications that process many concurrent asynchronous I/O requests can do so more quickly and efficiently by using I/O completion ports than by creating threads at the time of the I/O request. When you create a completion port, you can specify a concurrency value which limits the #threads associated with the port. Typically this number = #processors.

The CreateIoCompletionPort function lets you associate a file handle with an I/O completion port. When the async I/O completes, an I/O completion packet is queued to the port. A thread can use the GetQueuedCompletionStatus to wait for a packet to be queued; instead of directly waiting for the async I/O to be completed. Threads that block are released in LIFO order. The most efficient case is when no waits in the queue can be satisfied because the port has reached its concurrency limit - because in this case, when a running thread calls GetQueuedCompletionStatus, it picks up the queued packet immediately, and no context switch happens. The running thread continuously picks up packets and other threads are not able to run. The PostQueuedCompletionStatus function allows your app to queue its own I/O packets to the port without starting an async I/O. This is the way you would notify worker threads of some events that your app is aware of.

Read this article for a good example: https://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/reading_asynchronously_with_io_completion_ports.asp