基于完成端口的线程池的设计

 

                                     
contributed by DavidRipple 2005/04/11
1. 什么是线程池?
    线程池就是一堆的线程的管理器。为什么需要它呢?通常为了提供应用的响应速度,我们都喜欢为每个业务处理开一个线程。在正常情况下,这些线程是可管理的。但是,但系统有突发的异常事务流时,如果还狂开线程就可能会导致系统资源耗尽或系统崩溃,起码也会造成系统不稳定。线程池就是对线程的数量和状态进行实时监控,通过设置最大线程数量和平衡线程数量来使线程的使用平缓化,努力使整个系统中的线程数量在我们预先设定的平衡线程数量附近摆动。
 
2. 基于完成端口的线程池的设计思想
    以前看过<>,里面有一个线程池的实现。但那个实现可能是采取EVENT来实现的,我不大记得了但最近看了基于完成端口的实现,感觉思路非常清晰。其基本思想如下:
    系统创建了两个完成端口,一个用于管理线程,一个为众多的工作者线程所共享。我们为每一个工组者线程关联一个线程的状态结构,利用std::map建立一个线程ID到这个状态的映射。管理线程每隔几秒钟便检查系统中的线程状态,进行线程数量的动态调整。工作者线程就不断的在绑定的完成端口上等待任务,或管理线程发过来的管理命令,并贯彻执行。
 
3. 用完成端口来设计线程池有哪些优点?
   优点真是太多了,呵呵^_^,首先完成线程支持等待超时,可被管理线程用来做周期处理;其次,我们可以自己订制完成消息通过PostQueuedCompletionStatus来发送,任何完成线程都可能接受到这个消息;PostQueuedCompletionStatus发过来的消息只能被一个完成线程消费,并且消费此消息的完成线程当时肯定是空闲的,当时正埋头工作的完成线程是接收不到这个完成消息。这个特性正好可以被用于系统的线程数量的动态调整。Fantastic!!!!
 
4. 代码解释
 
管理线程实现:
unsigned __stdcall TThreadPool::ManagerProc(void* p)
{
   TThreadPool* pServer = (TThreadPool*) p;
   HANDLE   IoPort = pServer->GetMgrIoPort();
   unsigned long pN1, pN2;
   OVERLAPPED* pOverLapped;
   BOOL   bExit = FALSE;
   LABEL_MANAGER_PROCESSING:
   while (::GetQueuedCompletionStatus(IoPort, &pN1, &pN2, &pOverLapped, pServer->GetMgrWaitTime()))
   {
      if (pOverLapped == (OVERLAPPED*) 0xFFFFFFFF)
      {
         bExit = TRUE;
         break;
      }
   }
   if (::GetLastError() == WAIT_TIMEOUT && !bExit)
   {
      if (pServer->GetThreadPoolStatus() == TThreadPool::BUSY) pServer->AddThreads();
      if (pServer->GetThreadPoolStatus() == TThreadPool::IDLE) pServer->RemoveThreads();
      goto LABEL_MANAGER_PROCESSING;
   }
   return (0);
}
 
 
工作者线程实现:
unsigned __stdcall TThreadPool::WorkerProc(void* p)
{
   TThreadPool* pServer = (TThreadPool*) p;
   HANDLE   IoPort = pServer->GetWorkerIoPort();
   unsigned long pN1, pN2;
   OVERLAPPED* pOverLapped;
   DWORD   threadId = ::GetCurrentThreadId();
   while (::GetQueuedCompletionStatus(IoPort, &pN1, &pN2, &pOverLapped, INFINITE))
   {
      if (pOverLapped == (OVERLAPPED*) 0xFFFFFFFE)
      {
         pServer->RemoveThread(threadId);
         break;
      }
      else if (pOverLapped == (OVERLAPPED*) 0xFFFFFFFF)
      {
         break;
      }
      else
      {
         pServer->ChangeStatus(threadId, true);
         pfnWork pWork = reinterpret_cast < pfnWork > (pN1);
         unsigned uRet = pWork((void*) pN2);
         pServer->ChangeStatus(threadId, false);
      }
   }
   return (0);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值