Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4067973
  • 博文数量: 251
  • 博客积分: 11197
  • 博客等级: 上将
  • 技术积分: 6862
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-05 14:41
个人简介

@HUST张友东 work@taobao zyd_com@126.com

文章分类

全部博文(251)

文章存档

2014年(10)

2013年(20)

2012年(22)

2011年(74)

2010年(98)

2009年(27)

分类: LINUX

2011-11-17 12:22:56

线程池服务模型是single thread request per thread两种模型的折中方案,其在实现时通常需要借助任务队列,主线程往任务队列尾添加任务,线程池中的服务线程不断从任务队列头取任务并服务,如下图所示:

 

 

对于主线程和服务线程来说,任务队列是临界资源,需要加锁进行保护。主线程往任务队列添加任务时需要加锁,服务线程从任务队列取任务也许加锁,当服务线程发现任务队列空时需等待(主线程往任务队列中加任务时唤醒等待的服务线程),同时当队列满时,主线程需等待,当服务线程取走一个任务时唤醒主线程,为简化问题,假设任务队列是无限大的即主线程不需要等待。

 

主线程:

  1. pthread_mutex_lock(&lock);
  2. queue.push(task);
  3. pthread_mutex_unlock(&lock);
  4. pthread_cond_signal(&cond)


服务线程:

  1. while(true) {
  2.     pthread_mutex_lock(&lock);
  3.     while(queue.empty() == true) {
  4.          pthread_cond_wait(&cond, &lock);
  5.     }
  6.     task = queue.pop();
  7.     pthread_mutex_unlock(&lock);
  8.     server(task);
  9. }


上面的代码片段中,最难理解的应该红色字体部分了,为什么要用while循环,而不是if,这是因为pthread_cond_signal存在假唤醒(如信号等的影响)的情形,pthread_cond_signalman手册中是这么描述的:


The pthread_cond_signal() function shall unblock at least one of the threads that are blocked on the specified condition variable cond (if any threads are blocked on cond).

 

对于线程池的模型,假设某一时任务队列为空,这时所有的服务线程调用pthread_cond_wait,接着主线程往任务队列中添加一个任务,并调用pthread_cond_signal,这是可能有多个服务线程(unblock at least one被唤醒,假设有两个服务线程被唤醒,如果使用if,这时两个线程都会调用pop,其中一个必然会失败,如果queue实现得不够好,可能引发大的错误,stlqueue为空时,调用frontback的行为是未定义的。

 

阅读(4488) | 评论(3) | 转发(1) |
给主人留下些什么吧!~~

zyd_cu2011-11-27 13:42:52

Arthur1989: 其实可以每个线程自己对应一条任务队列的,博主可以参考下memcached的实现......
的确是这样,尤其是在高并发请求的条件下是有用的。

zyd_cu2011-11-27 13:42:46

Arthur1989: 其实可以每个线程自己对应一条任务队列的,博主可以参考下memcached的实现......
的确是这样,尤其是在高并发请求的条件下是有用的。

Arthur19892011-11-26 15:23:17

其实可以每个线程自己对应一条任务队列的,博主可以参考下memcached的实现.