HANDLE CreateIoCompletionPort ( HANDLE FileHandle, // handle to file HANDLE ExistingCompletionPort, // handle to I/O completion port ULONG_PTR CompletionKey, // completion key DWORD NumberOfConcurrentThreads // number of threads to execute concurrently );
创建完成端口以及将文件句柄与完成端口关联都采用此函数。
1、创建完成端口
ExistingCompletionPort必须为NULL
如果FileHandle为INVALID_HANDLE_VALUE,则创建的完成端口不与任何文件句柄关联(可以后续再通过此函数关联),此时,剩下的两个参数会被忽略
如果FileHandle不为INVALID_HANDLE_VALUE,则创建的完成端口与此文件句柄关联
NumberOfConcurrentThreads为并发线程个数,MSDN建议为CPU个数,一般常用的经验公式是2*CPUNum或者2*CPUNum+2
2、关联文件句柄
FileHandle必须有效,可以为CreateFile 函数用FILE_FLAG_OVERLAPPED标记打开的句柄 ,或是socket 或accept 函数返回的socket句柄
ExistingCompletionPort为已创建完成端口句柄
dwCompletionKey相当于一个文件句柄的关联参数,在关联文件句柄与完成端口时使用的此参数,将跟随至每一个与该完成端口相关的包。
最后一个参数可以忽略
BOOL GetQueuedCompletionStatus( HANDLE CompletionPort, // handle to completion port LPDWORD lpNumberOfBytes, // bytes transferred PULONG_PTR lpCompletionKey, // file completion key LPOVERLAPPED *lpOverlapped, // buffer DWORD dwMilliseconds // optional timeout value );
此函数从完成端口获取一个I/O完成包。
lpCompletionKey是此包关联的文件句柄在关联完成端口时设置的,通过此参数可以判断此包为哪个文件句柄所有
lpOverlapped是各个发起重叠IO事件的函数设置的OVERLAPPED结构体指针。下列函数可以隐式地发起重叠IO事件
ConnectNamedPipe DeviceIoControl LockFileEx ReadDirectoryChangesW ReadFile TransactNamedPipe WaitCommEvent WriteFile http://69.10.233.10/KB/IP/SimpleIOCPApp.aspx http://www.codeproject.com/KB/IP/iocp-multicast-udp.aspx http://www.codeproject.com/KB/cs/managediocp.aspx http://www.gamedev.net/community/forums/topic.asp?topic_id=283907 http://www.codeproject.com/KB/IP/IOCompletionPort.aspx http://msdn.microsoft.com/en-us/library/aa365198(VS.85).aspx
如上所述,并无法获取数据缓冲区的指针,所以,一般来说。在调用时,会定义这么一个结构体struct Context{OVERLAPPED* lpOverLapped;
LPVOID lpBuf;
};分别把其中的lpOverLapped指针和lpBuf指针作为参数使用,那么当调用上述函数时,可以获取lpOverLapped指针,而将lpOverLapped指针强制转化为Context指针就可以获取缓冲区指针了。可以强制转换的理由是他们的地址是相同的
BOOL PostQueuedCompletionStatus( HANDLE CompletionPort, // handle to an I/O completion port DWORD dwNumberOfBytesTransferred, // bytes transferred ULONG_PTR dwCompletionKey, // completion key LPOVERLAPPED lpOverlapped // overlapped buffer );此函数显式地投递一个IO重叠事件相关链接