Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3209379
  • 博文数量: 1805
  • 博客积分: 135
  • 博客等级: 入伍新兵
  • 技术积分: 3345
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-19 20:01
文章分类

全部博文(1805)

文章存档

2017年(19)

2016年(80)

2015年(341)

2014年(438)

2013年(349)

2012年(332)

2011年(248)

分类:

2015-06-24 08:38:08

原文地址:线程池和工作队列 作者:xiaosuo

前文我已经通过理发师的故事讲述了服务器程序的设计及其演变过程,不知道各位看客是否能理解其中的奥妙。本问将着重介绍线程池和工作队列的相关问题,其后还将给出自己设计的api及源码。

线程池(Thread Pool)

这又是一个能顾名思义的名字(好的事物都是如此),既然我们大家都清楚鱼池,那么肯定也就能理解线程池就是用来盛放线程(不要告诉我:你不知道什么是线程哦)的。

对于一个事物,如果不知道它产生的背景似乎是不妥的,因为那样你将不能很好的理解他和灵活地应用它。在理发师的故事中,理发师为了缩短把学徒从后厅叫到前厅的时间,规定了在前台等待的学徒的数目。这映射到服务器上就变成了规定预先创建的线程数,缩短线程创建的时间从而加快了系统响应速度减少线程创建和销毁的开销。由于服务器要预先创建一定数目的线程,所以这个技术,也叫作线程预创建技术

最简单的线程池中的线程数目是固定的,每当一个任务来临时,都会找一个目前空闲的线程来处理这个任务,如果没有空闲线程可用,那么将报错;处理任务的线程做完任务后并不是马上退出而是将自己标示成空闲,然后休眠等待新任务。由于服务器的负载在时间上并不是平均分配的,如果存在大量的空闲线程,对服务器资源也是一种浪费,所以现实中的线程池实现都支持动态调整线程数。一个典型的设计可以分别设置所有线程数和空闲线程数的最大和最小值,当空闲线程比较小的时候,服务器会增加线程,反之亦然。对于增加线程的时机,主要有两个:分配任务时和任务结束时,因为在分配任务时增加线程会增加服务器的响应时间,所以在我下面的实现中采用的是在任务结束时增加线程。

线程池还有一个附加的作用,它能够控制机器上的并发任务数,使其不超过某个极限值,也算是一种安全增强。

工作队列

就是存放工作(任务)的队列,其中的“队列”也道出了任务先进先出(FIFO)的性质。

有人倾向于把工作队列作为线程池的一部分来实现,个人认为这是不恰当的。因为工作队列在任务的响应时间上没有保证,而线程池则提供当前有没有空闲线程可以处理这个任务的信息,两者在语意上完全不同。但是,没有保证也并不总是坏事,对于超载的请求,它用延迟处理代替了拒绝服务,平滑了迸发请求对服务器的冲击,这种缓冲机制对于一些对时间不是很敏感地且服务时间较短的服务(HTTP服务就是此类)还是很适合的。

API

我所设计的C语言API如下,比较简单明了,相信不用我再解释什么了。

XSThreadPool* xs_thread_pool_create(int min, int max, int idle_min,
                int idle_max);
int xs_thread_pool_do(XSThreadPool *tp, xs_thread_func_t func, void *args);
int xs_thread_pool_destroy(XSThreadPool *tp);


XSWorkQueue* xs_work_queue_create(int max, int tp_min, int tp_max,
                int tp_idle_min, int tp_idle_max);
int xs_work_queue_enqueue(XSWorkQueue *q, xs_thread_func_t func,
                xs_thread_func_t cleanup, void *args);
int xs_work_queue_destroy(XSWorkQueue *q);


关于xs_这个前缀,是我网名xiaosuo的缩写,实在想不出什么好名字。

有必要提醒一下:任务之间不要再用pthread_cancel来同步,不要用pthread_exit来退出,不然后果自负。

后记

在Linux下用线程搞开发,确实比较累,稍不留心就有可能造成死锁,希望此类事情不要在上述代码中再次发生,调试过程中因为pthread_mutex_lock不是取消点(cancel point)所导致的死锁已经让我焦头烂额了。

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