Chinaunix首页 | 论坛 | 博客
  • 博客访问: 68995
  • 博文数量: 24
  • 博客积分: 25
  • 博客等级: 民兵
  • 技术积分: 80
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-07 00:11
文章分类

全部博文(24)

文章存档

2014年(10)

2013年(7)

2012年(7)

我的朋友

分类: LINUX

2014-10-23 23:35:50

原文地址:网络编程问题总结(六) 作者:zyd_cu

线程池服务模型是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的行为是未定义的。

 

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