1.IOCP是什么
IOCP是Input/Output Completion Ports的简称,中文翻译为完成端口,完成是应用程序向系统发起一个IO操作,系统会在操作结束后,将IO操作完成结果通知应用程序,端口指的是机制
2.重叠IO(Overlapped)
针对一个Socket可以发起多个IO操作,无需等待上一个IO完成,尽管调用IO操作是按顺序的,但是IO操作完成通知是随机的无序的
3.实现流程
2.原理
IOCP的基本原理是通过事件驱动的方式来处理I/O请求,以避免传统的阻塞式I/O操作带来的性能问题,具体来说,IOCP通过一下几个步骤完成异步I/O操作:
- 1.应用程序首先创建一个或多个 I/O 端口,并将它们关联到套接字或文件句柄上
- 2.当应用程序需要进行 I/O 操作时,它调用系统级别的 API,将请求提交到 I/O 端口上
- 3.操作系统内核将 I/O 请求与相应的 I/O 端口关联,并立即返回,使得应用程序可以继续执行其他操作。
- 4.内核在后台异步地执行 I/O 操作,并将结果存储在完成队列中。
- 5.当 I/O 操作完成时,内核会通知完成端口,并将完成信息添加到完成队列中。
- 6.应用程序通过调用 GetQueuedCompletionStatus() 函数获取完成队列中的已完成请求,并按需处理它们。
- 7.如果完成队列为空,则应用程序可以等待新的完成事件发生,或者继续执行其他操作。
3.函数
3.1CreateIoCompletionPort
这个函数是个本身具有多重功能的函数(Windows平台上这样的函数并不多),需要用不同的方式来调用,以实现不同的功能
HANDLE WINAPI CreateIoCompletionPort(
__in HANDLE FileHandle,
__in HANDLE ExistingCompletionPort,
__in ULONG_PTR CompletionKey,
__in DWORD NumberOfConcurrentThreads
);
- 创建内核
HANDLE hICP = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,1);
前三个参数在这种情况下是没有意义的,只需要全部传递NULL即可,第一个参数不是NULL而是INVALID_HANDLE_VALUE,因为第一个参数按照定义是一个文件的句柄,也就是需要IOCP操作的文件句柄,而代表“NULL”文件句柄的实际值是INVALID_HANDLE_VALUE,这是因为NULL实际等于0,而0这个文件句柄被用于特殊用途,所以要用INVALID_HANDLE_VALUE来代表“NULL”意义的文件,INVALID_HANDLE_VALUE的值是-1或者0xFFFFFFFF。最后一个参数NumberOfConcurrentThreads默认的推荐值就是CPU个数的2倍了
3.2GetQueuedCompletionStatus
BOOL WINAPI GetQueuedCompletionStatus(
__in HANDLE CompletionPort,
__out LPDWORD lpNumberOfBytes,
__out PULONG_PTR lpCompletionKey,
__out LPOVERLAPPED* lpOverlapped,
__in DWORD dwMilliseconds
);
- 第一个参数就是我们之前创建的那个完成端口内核对象的句柄,这个参数实际也就是告诉系统,我们当前的线程是归哪个完成端口对象来调度。
- 第二个参数是一个比较有用的参数,在函数返回后它将告诉我们这一次的IO操作实际传输或者接收了多少个字节的信息,这对于我们校验数据收发完整性非常有用。
- 第三个参数是与完成端口句柄绑定的一个一对一的数据指针
- 第四个参数就是重叠操作的数据结构
- 第五个参数是一个等待的毫秒数