GetQueuedCompletionStatus函数有个
OVERLAPPED结构,很多资料上都采用不同的
结构体来扩展该结构,比如有的资料定义
调用函数,GetQueuedCompletionStatus(hIocp, &dwBytesXfered,(PULONG_PTR)&PerHandleKey, &Overlap, INFINITE);最后一个参数为等待时间,为INFINITE时直至有信号返回。
函数返回后,一般使用OverlapPlus = CONTAINING_RECORD(Overlap, OVERLAPPEDPLUS, ol)得到一些信息。这是一个宏,查找Overlap在哪个OVERLAPPEDPLUS结构体的ol元素中,并返回这个结构体的指针。我们在设计结构体的时候,一般加入重叠结构,操作类型,这样就可以判断这个重叠结构对应的是哪一个操作。
因为是非堵塞的,等于投递到与
套接字相关联的
完成端口上,系统会把把WSASend对应的缓冲区提交到底层缓冲,也可以把WSARecv投递的缓冲区,用接收到的数据填充,每一个WSASend,WSARecv,都应有新申请一个overlaspped plus结构提交,以存放本次投递的IO操作的相关数据,——单IO操作数据所以工作器线程中,从完成端口队列中get得到一个完成包的时候,可以根据单句柄数据知道在这个完成端口上是哪一个套接字投递的IO操作完成了,从get到的
overlapped中得到相关的已经完成IO数据和信息,并作相应的处理。比如投递了1M,完成包却告知只完成512K,那么你就知道要把余下的512K继续投递WSASend,当然上一个WSASend的
Overlapped这个时候可以重用到下一个WSASend中,这个是允许的,可以用一个字段存放全部1M,把余下未Send成功512k放到wbuf中,继续投递或者投递WSARecv1M数据,却收到一个512K的完成通知,那么你要继续投递WSARecv,当然前一个WSARecv的
overlapped也可以重用,不过需要一些处理,把已经接收到的512K保存到某个字段中,再投递一个512K的请求去接收
完成端口内部,对投递的Overlapped的填充,好像只有WSARecv的时候填充WSABUF,其他都是投递IO前,代码中显式填充,并投递的。至于完成了多少个字节,是在lpNumberOfBytes中得到。
实现从指定的
IOCP获取CP。当CP队列为空时,对此函数的调用将被阻塞,而不是一直等待I/O的完成。当CP队列不为空时,被阻塞的线程将以后进先出(LIFO)顺序被释放。对于IOCP机制,它允许多线程并发调用GetQueuedCompletionStatus函数,最大
并发数是在调用
CreateIoCompletionPort函数时指定的,超出最大并发数的调用线程,将被阻塞。函数解释如下:
lpoverlapped:为调用IOCP机制所引用的
OVERLAPPED结构。