完成端口是windows为了处理不同设备之间并发运行时运行速度差异而设计的一种异步数据处理的机制。完成端口是《windows核心编程》中的一个重点内容,最近我花了三天时间读完核心编程里面关于完成端口的章节,并了解微软相关的技术资料文档,感觉完成端口的设计和实现可以在一定程度上加快windows的服务速度,用不用完成端口对程序逻辑没什么影响,但对于需要速度的服务来说,这就至关重要了。由于源码不公开的缘故,一些内部原理只能够猜,而且很多参数的使用彼此关联,有一定的迷惑性,个人觉得微软的这些底层接口一开始就设计不好,加上后来为了兼容早前版本开发的程序,错而不改,越来越乱。
即使如此,只要细心也足以学习好怎样使用完成端口。可以说,对于windows程序员,对完成端口的掌握程度显示程序员的平台底层技术水平。
1. 三个基本函数,看似不多,把参数弄清楚还是需要不少时间的。
CreateIoCompletionPort()
PostQueuedCompletionStatus()
GetQueuedCompletionStatus()
2. 创建完成端口
使用HANDLE hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,dwThreadCount);创建完成端口,这里要注意参数的设置,与原本windows设计的初衷有区别了。最后一个参数是指定完成端口内核对象工作时最多开辟的线程数,线程的管理由完成端口内核对象管理,对用户不透明。原型如下:
HANDLE WINAPI CreateIoCompletionPort(
_In_ HANDLE FileHandle,
_In_opt_ HANDLE ExistingCompletionPort,
_In_ ULONG_PTR CompletionKey,
_In_ DWORD NumberOfConcurrentThreads
);
请参考:http://msdn.microsoft.com/en-us/library/windows/desktop/aa363862(v=vs.85).aspx
3. 设备句柄与完成端口关联(相当一个注册动作)
CreateIoCompletionPort(hFileRead,hIOCP,CK_READ,0);这里hFileRead是对应设备的句柄(这里的设备可以是windows文件系统泛用的设备的意思),hIOCP是已经存在的完成端口句柄;CK_READ是设置为完成端口事件完成时发出的通知的参数,可以分辨这个完成的事件是哪个设备的;后面我们用到的例子就使用了CK_READ与CK_WRITE去分辨已经完成的事件是哪个设备发出的。
4. 手动通知内核,事件已完成,即把完成事件放到