I think it is the most direct way to look at MSDN by myself. Other people's introductions are full of chews? The IO completion port provides an efficient thread model for processing multiple asynchronous IO requests in a multi-processor system. When a process creates a completion port, the operating system creates a queue object to serve these requests. By using IO to complete the port and the associated pre-allocated thread pool, rather than creating a new thread to process the current request, processing multiple concurrent asynchronous IO requests will be faster and more effective. How to create an IO completion port using the CreateIoCompletionPort function, and associate one or more file descriptors on the port ]. When one or more asynchronous IO operations on these operators are completed, one IO completion packet enters the first-in-first-out queue associated with the IO completion port. A powerful usage of this mechanism is to synchronize multiple descriptors in a single object, even though they have other useful applications. Note: Data packets in the queue may be listed in different order. [This sentence is not easy to understand. Is it true that multiple threads operate in the column ?] Note: A file handle is a System Abstraction representation that represents overlapping IO endpoints, not just the file on the disk. For example, it can be a network endpoint, TCP socket, named pipe, or mail slot. Any system object that supports port completion can be exploited. When a file handle is associated with a completion port, the status block passed in will not be updated until the packet is removed from the completion port. the only exception is if the original operation returns synchronously with an error. A thread (either one created by the main thread or the main thread itself) uses the GetQueuedCompletionStatus function to wait for a completion packet to be q Ueued to the I/O completion port, rather than waiting directly for the asynchronous I/O to complete. threads that block their execution on an I/O completion port are released in last-in-first-out (LIFO) order, and the next completion packet is pulled from the I/O completion port's FIFO queue for that thread. this means that, when a completion packet is released to a thread, the system releases Last (most recent) thread associated with that port, passing it the completion information for the oldest I/O completion. when the descriptor is associated with a completion port, the passed status will not be updated until the packet is removed from the completion port. The only exception is the asynchronous Return Error of the original operation. A thread (which can be created by the main thread or the main thread itself) uses the GetQueuedCompletionStatus function to wait for the package to enter the completed port, rather than waiting for asynchronous IO to complete. The thread that completes the port blocking operation will be released later, and the next port package of this thread will be removed from the IO port in the first-in-first-out queue. This means that when a package is fed to a thread, the system will release the last Thread associated with the port, at the same time, complete the port information for the oldest completed port ]. Although any thread can call GetQueuedCompletionStatus to a specific completion port, when a specific thread calls it for the first time, it starts to associate with a specific completion port to know one of the following three situations: 1. the thread exists and is associated with another completion port; 2. the completion port is disabled. That is to say, a thread can be associated with only one completion port. When a completion package is placed in the completion port queue, the system first checks the number of threads associated with the port. If the number of running threads is smaller than the concurrency value, the most recent waiting thread is allowed to process the finished package. When a running thread finishes processing, it will continue to call GetQueuedCompletionStatus again, because at this point it either waits for the next Completion package or waits for the packet queue to be empty. The thread can call PostQueuedCompletionStatus to ship the packet to the queue of the IO port. In this way, the completion port can be used to collect the interactive data of other threads or processes, and the completion port package can also be collected from the IO system. The PostQueuedCompletionStatus function allows an application to deliver a specific package to the IO completion port without enabling asynchronous IO operations. For example, this is useful for non-Event Notification worker threads. I/O completion port handle and each descriptor handle are associated with a specific I/O completion port and are considered to have received the completion port. When there is no reference associated with it, the completion port is released. Therefore, all these handles must be appropriate to release the system resources associated with the completed port. After these conditions are met, call CloseHandle to close the port handle. Note that a complete port is associated with the created port and cannot be shared between processes. However, a single handle can be shared among different threads of the same process. The most important attribute of threads and concurrent I/O Completion Ports is the concurrency value. The concurrent value of the completion port is determined through the theNumberOfConcurrentThreads parameter of CreateIoCompletionPort. This value limits the number of threads associated with the completion port. When the number of associated threads exceeds this concurrency value, the system will block any subsequent threads until the number of running threads drops to the concurrency value. The most effective syntax is that when there are finished packets in the queue, but there is no waiting, it will be satisfied because the port has reached the concurrency limit. Considering the concurrency value, one or more threads are used to wait for the call at GetQueuedCompletionStatus. In this case, if the queue has a complete package waiting, when the running thread calls GetQueuedCompletionStatus, it will not block, because as mentioned above, the thread queue is first-in-first-out. Instead, the thread will immediately get the next Completion package. There is no context switch, because the running thread continuously obtains the complete package, and other threads cannot run [How to understand this section ]. Note: In the previous example, the additional thread seems useless and does not allow it. However, it is assumed that the running thread stops or closes the associated completion port because some synchronization mechanisms never enter the waiting state. Note the execution branches of all these threads when re-designing the application. The optimal maximum concurrency is the number of CPUs on the computer. If your transmission requires a complex calculation, it requires a large concurrency value. Each completion package may increase the completion time, but more completion packages can be processed concurrently. You can test and set the concurrency value to optimize the program. When a Thread associated with the same completion port is waiting for some reasons (such as the SuspendThread function), the other thread waits for the GetQueuedCompletionStatus to process the completion package. When the waiting thread starts running, it will be a short process when the number of active threads exceeds the concurrency value. However, the system will quickly reduce the number of active threads by not allowing any new active threads to be started until the number of active threads drops to the concurrency value. This is also why you can create a thread with more concurrent values in the thread pool. Thread Pool Management is beyond the scope of this topic, but a good experience is that the thread pool has at least two times the number of system processors (> = 2 * corenum ). Refer to Thread Pools. The following functions can be used to start IO operations by completing the port. You must pass an instance of the OVERLAPPED structure and the descriptor associated with the IO to these functions (by calling CreateIoCompletionPort) to enable the IO completion port mechanism: Invalid oWSASendWSARecvFromWSARecvMsgWSARecvok, translated, A lot of sentences are not fluent. I don't understand them in some places!