GetQueuedCompletionStatus(
HANDLE Comp1etionPort,
LPDWORD lpNumber0fBytesTransferred,
LPDWORD lpCompletionKey,
LPOVERLAPPED * lpOverlapped,
DWORD dwMilliseconds
);
其中,CompletionPort参数对应与要在上面等待的完成端口.1pNumberOfBytesTransferred参数负责在完成了—次I/O操作后(如WSASend或WSARecv)、接收实际传输的字节数。lpCompletionKey参数为原先传递进入CreateCompletionPort函数的套接字返回“单句柄数据”。如我们早先所述,大家最好将套接字句柄保存在这个“键”(Key)中。1pOverlapped参数用于接收完成的I/O操作的重叠结果。这实际是—个相当重要的参数,因为要f用它获取每个I/O操作的数据。而最后一个参数。DwMilliseconds用于指定调用者希望等待一个完成数据包在完成端门上出现的时间。假如将其设为INFINITE。调用会无休止地等持下去。
例子:
http://search.csdn.net/Expert/topic/1038/1038972.xml?temp=.1748926
==============================
GetQueuedCompletionStatus函数。实现从指定的IOCP获取CP。当CP队列为空时,对此函数的调用将被阻塞,而不是一直等待I/O的完成。当CP队列不为空时,被阻塞的线程将以后进先出(LIFO)顺序被释放。对于IOCP机制,它允许多线程并发调用GetQueuedCompletionStatus函数,最大并发数是在调用CreateIoCompletionPort函数时指定的,超出最大并发数的调用线程,将被阻塞。函数解释如下:
声明:
BOOL GetQueuedCompletionStatus(
HANDLE CompletionPort,
LPDWORD lpNumberOfBytes,
PULONG_PTR lpCompletionKey,
LPOVERLAPPED *lpOverlapped,
DWORD dwMilliseconds);
调用参数:
CompletionPort:指定的IOCP,该值由CreateIoCompletionPort函数创建。
lpnumberofbytes:一次完成后的I/O操作所传送数据的字节数。
lpcompletionkey:当文件I/O操作完成后,用于存放与之关联的CK。
lpoverlapped:为调用IOCP机制所引用的OVERLAPPED结构。
dwmilliseconds:用于指定调用者等待CP的时间。
返回值:
调用成功,则返回非零数值,相关数据存于lpNumberOfBytes、lpCompletionKey、lpCompletionKey变量中。失败则返回零值。
----------------
ostQueuedCompletionStatus函数提供了一种方式来与线程池中的所有线程进行通信。如,当用户终止服务应用程序时,我们想要所有线程都完全利索地退出。但是如果各线程还在等待完成端口而又没有已完成的I/O 请求,那么它们将无法被唤醒。
通过为线程池中的每个线程都调用一次PostQueuedCompletionStatus,我们可以将它们都唤醒。每个线程会对GetQueuedCompletionStatus的返回值进行检查,如果发现应用程序正在终止,那么它们就可以进行清理工作并正常地退出。
使用这种线程终止技术须保证线程池中的线程正在退出,不会再次调用GetQueuedCompletionStatus。如果想要通知线程池中的每个线程发生了某些事情,让它们进入下一次循环并再次调用GetQueuedCompletionStatus:问题就来了,这是因为线程是以后入先出的方式被唤醒的。因此,为了确保线程池中的每个线程都能有机会得到模拟的I/O项,还必须在应用程序中采用其它线程同步机制,否则,同一个线程可能会多次得到相同的通知。
Vista中,当调用CloseHandle并传入一个完成端口的句柄时,系统就会将所有正在等待GetQueuedCompletionStatus返回的线程唤醒。并返回FALSE给它们。此时调用GetLastError会返回ERROR_INVALID_HANDLE。线程可以通过这种方式来知道自己应该得体地退出了。--
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。