BOOL PostQueuedCompletionStatus(
HANDLE CompletlonPort,
DW0RD dwNumberOfBytesTrlansferred,
DWORD dwCompletlonKey,
LPOVERLAPPED lpoverlapped,
);
其中,CompletionPort参数指定想向其发送一个完成数据包的完成端口对象。而就dwNumberOfBytesTransferred,dwCompletionKey和lpOverlapped这三个参数来说.每—个都允许我们指定—个值,直接传递给GetQueuedCompletionStatus函数中对应的参数。这样—来。—个工作者线程收到传递过来的三个GetQueuedCompletionStatus函数参数后,便可根据由这三个参数的某一个设置的特殊值,决定何时应该退出。例如,可用dwCompletionPort参数传递0值,而—个工作者线程会将其解释成中止指令。一旦所有工作者线程都已关闭,便可使用CloseHandle函数,关闭完成端口。最终安全退出程序。
PostQueuedCompletionStatus函数提供了一种方式来与线程池中的所有线程进行通信。如,当用户终止服务应用程序时,我们想要所有线程都完全利索地退出。但是如果各线程还在等待完成端口而又没有已完成的I/O 请求,那么它们将无法被唤醒。
通过为线程池中的每个线程都调用一次PostQueuedCompletionStatus,我们可以将它们都唤醒。每个线程会对GetQueuedCompletionStatus的返回值进行检查,如果发现应用程序正在终止,那么它们就可以进行清理工作并正常地退出。
PostQueuedCompletionStatus功能函数向一个已经初始完的I/O端口发送数据包,触发GetQueuedCompletionStatus功能调用函数来取得数据包
- BOOL PostQueuedCompletionStatus(
- HANDLE CompletionPort, // handle to an I/O completion port
- DWORDdwNumberOfBytesTransferred, // value to return via GetQueuedCompletionStatus' lpNumberOfBytesTranferred
- DWORD dwCompletionKey, // value to return via GetQueuedCompletionStatus' lpCompletionKey
- LPOVERLAPPED lpOverlapped // value to return via GetQueuedCompletionStatus'lpOverlapped
- );
BOOL PostQueuedCompletionStatus(
HANDLE CompletionPort, // handle to an I/O completion port
DWORDdwNumberOfBytesTransferred, // value to return via GetQueuedCompletionStatus' lpNumberOfBytesTranferred
DWORD dwCompletionKey, // value to return via GetQueuedCompletionStatus' lpCompletionKey
LPOVERLAPPED lpOverlapped // value to return via GetQueuedCompletionStatus'lpOverlapped
);
以上PostQueuedCompletionStatus的三个参数的值正好由GetQueuedCompletionStatus函数接收
- 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
- );
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
);
线程中,不断的执行GetQueuedCompletionStatus来从消息队列中读取数据
例如某一线程执行函数RepetitionRun:
- //Run函数
- bool CQueueServiceThread::RepetitionRun()
- {
- //效验参数
- GT_ASSERT(m_hCompletionPort!=NULL);
- //变量定义
- DWORD dwThancferred=0;
- OVERLAPPED * pOverLapped=NULL;
- CQueueService * pQueueService=NULL;
- //等待完成端口
- if (GetQueuedCompletionStatus(m_hCompletionPort,&dwThancferred,(PULONG_PTR)&pQueueService,&pOverLapped,INFINITE))
- {
- //判断退出
- if (pQueueService==NULL) return false;
- //获取数据
- tagDataHead DataHead;
- bool bSuccess=pQueueService->GetData(DataHead,m_cbBuffer,sizeof(m_cbBuffer));
- GT_ASSERT(bSuccess==true);
- //处理数据
- if (bSuccess==true) pQueueService->OnQueueServiceThread(m_cbThreadIndex, DataHead,m_cbBuffer,DataHead.wDataSize);
- return true;
- }
- return false;
- }
- CreateIoCompletionPort则是创建消息队列
- 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
- );