<!--[endif]-->前言
本文不是全面介绍完成端口的,只是简单介绍了一下完成端口和几个常用概念。本文主要关注完成端口关闭时资源释放问题。
完成端口——可能是Win32下最复杂的一种I/O模型,Win32下最复杂的内核对象。它通过指定数量的线程对重叠I/O请求进行管理,以便为已经完成的I/O请求提供服务,相对其它I/O模型,它管理任意数目I/O套接字。假若一个应用程序同时需要管理为数众多的套接字,那么采用这种模型,往往可以达到最佳的系统性能。
通过CreateIoCompletionPort(唯一一个创建内核对象而没有LPSECURITY_ATTRIBUTES参数的Win32函数,这是因为完成端口只应用于进程内)来创建I/O完成端口,当你创建一个I/O完成端口时,内核实际创建了5个不同的数据结构。
<!--[if !vml]--><!--[endif]-->
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
<!--[if !vml]--><!--[endif]-->
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
<!--[if !vml]--><!--[endif]-->
成功创建一个完成端口后,便可开始将套接字句柄与对象关联到一起。但在关联套接字之前,首先必须创建一个或多个“工作者线程”,以便在I/O请求投递给完成端口对象后,为完成端口提供服务。
完成端口I/O模型的工作流程如下:
1) 通过CreateIoCompletionPort创建完成端口。
2) 创建工作者线程。
3) 通过CreateIoCompletionPort将完成端口与某一设备相关联。
4) 通过WSAXXX发出异步I/O请求。
5) 在工作者线程中通过调用GetQueuedCompetionStatus取得完成I/O请求项进行后续的处理。
<!--[if !vml]--><!--[endif]-->HANDLE CreateIoCompletionPort(HANDLE FileHandle, HANDLE ExistingCompletionPort,
<!--[if !vml]--><!--[endif]--> ULONG_PTR CompletionKey, DWORD NumberOfConcurrentThreads);
<!--[if !vml]--><!--[endif]-->BOOL GetQueuedCompletionStatus (HANDLE CompletionPort, LPDWORD lpNumberOfBytesTransferred,
<!--[if !vml]--><!--[endif]--> PULONG_PTR lpCompletionKey, LPOVERLAPPED *lpOverlapped, DWORD dwMilliseconds );<!--[if !vml]--><!--[endif]-->
GetQueuedCompetionStatus的lpCompletionKey参数包含了“单句柄数据”,它是通过调用CreateIoCompletionPort来关联完成端口与设备时,通过CompletionKey参数设定的。也就是说这个数据特定于设备(这里指套接字)。
GetQueuedCompetionStatus的lpOverlapped参数则包含了“单I/O操作数据”,在通过该函数取得I/O完成队列中的I/O请求完成项后,lpOverlapped指向一个对应了发起这个I/O请求时传递的OVERLAPPED数据结构,也就是说这个数据特定于I/O请求。
单句柄数据和单I/O数据有什么用呢?同过单句柄数据我们可以关联特定的处理函数或处理器或其它结构对该句柄之上的I/O进行特定的处理。单I/O数据为异步I/O的发起和完成建立了联系,它可以关联缓冲区或处理器(参见ACE_Proactor),方便异步I/O操作。
下面是请求完成通知插入I/O完成队列的几种情况:
上述情况除正常完成和PostQueuedCompletionStatus外,其他完成通知会使GetQueuedCompletionStatus返回FALSE,而此时lpOverlapped(超时为NULL)指向未完成I/O请求的单I/O数据。明白了这些后,后面讲的大多不是问题,讲一讲加深下印象吧。
我们通常通过调用PostQueuedCompletionStatus向I/O完成队列中加入特殊的完成项来结束工作者线程的,此时,对于未完成的I/O请求要分情况处理之:
由于等待线程队列是LIFO的,所以该函数要想通知每个工作者线程是件棘手的事情。
[1]Jeffery Richter.Advanced Windows(3rd Edition),Microsoft Press,1997
[2]Anthony Jones,Jim Ohlund. Network Programming for Microsoft Windows ,Microsoft Press,2002