PostQueuedCompletionStatus 与 GetQueuedCompletionStatus

  PostQueuedCompletionStatus函数,向每个工作者线程都发送—个特殊的完成数据包。该函数会指示每个线程都“立即结束并退出”.下面是PostQueuedCompletionStatus函数的定义:
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功能调用函数来取得数据包

  1. BOOL PostQueuedCompletionStatus(  
  2. HANDLE CompletionPort,  // handle to an I/O completion port     
  3. DWORDdwNumberOfBytesTransferred,  // value to return via  GetQueuedCompletionStatus'  lpNumberOfBytesTranferred     
  4. DWORD dwCompletionKey,  // value to return via  GetQueuedCompletionStatus'  lpCompletionKey     
  5. LPOVERLAPPED lpOverlapped  // value to return via  GetQueuedCompletionStatus'lpOverlapped     
  6. );   
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函数接收

  1. BOOL GetQueuedCompletionStatus(  
  2.   HANDLE CompletionPort,       // handle to completion port   
  3.   LPDWORD lpNumberOfBytes,     // bytes transferred   
  4.   PULONG_PTR lpCompletionKey,  // file completion key   
  5.   LPOVERLAPPED *lpOverlapped,  // buffer   
  6.   DWORD dwMilliseconds         // optional timeout value   
  7. );   
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:

  1. //Run函数   
  2. bool CQueueServiceThread::RepetitionRun()  
  3. {  
  4.  //效验参数   
  5.  GT_ASSERT(m_hCompletionPort!=NULL);  
  6.  //变量定义   
  7.  DWORD dwThancferred=0;  
  8.  OVERLAPPED * pOverLapped=NULL;  
  9.  CQueueService * pQueueService=NULL;  
  10.  //等待完成端口   
  11.  if (GetQueuedCompletionStatus(m_hCompletionPort,&dwThancferred,(PULONG_PTR)&pQueueService,&pOverLapped,INFINITE))  
  12.  {  
  13.   //判断退出   
  14.   if (pQueueService==NULL) return false;  
  15.   //获取数据   
  16.   tagDataHead DataHead;  
  17.   bool bSuccess=pQueueService->GetData(DataHead,m_cbBuffer,sizeof(m_cbBuffer));  
  18.   GT_ASSERT(bSuccess==true);  
  19.   //处理数据   
  20.   if (bSuccess==true) pQueueService->OnQueueServiceThread(m_cbThreadIndex, DataHead,m_cbBuffer,DataHead.wDataSize);  
  21.   return true;  
  22.  }  
  23.  return false;  
  24. }  
  25. CreateIoCompletionPort则是创建消息队列  
  26. HANDLE CreateIoCompletionPort (  
  27.   HANDLE FileHandle,              // handle to file   
  28.   HANDLE ExistingCompletionPort,  // handle to I/O completion port   
  29.   ULONG_PTR CompletionKey,        // completion key   
  30.   DWORD NumberOfConcurrentThreads // number of threads to execute concurrently   
  31. );  

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值