Kernel Space

January 30, 2007

编程原语之三 — 线程池

Filed under: 编程珠玑 — agassi @ 12:04 pm

最近又需要实现一个线程池,所以说说这个topic。

当需要处理大量数据的时候,线程池是比较高效的办法。传统的方法是为每个任务创建一个线程,结果就是线程创建带来的开销。所以线程池采用的是线程的预创建技术。在开始处理数据之前,创建好一定数量的线程,同时在整个处理过程中,这些线程都一直存在不会退出。

在线程池内部,有一个queue用来维护等待处理的任务。在实现的过程中,我发现最主要的是做到这个线程的通用性,也就是和处理的具体任务无关。实际上跟具体任务有关的就是queue当中的元素类型和任务的处理函数。为了达到这个目的,我用如下结构和函数指针的定义:

typedef struct {
  int taskid;
  void* taskdata;
} task_t;
typedef void* (*disposer)(task_t);

 结构中使用了void*来表示一种通用的任务数据类型。disposer是具体的任务处理函数的一种抽象,参数就是一个任务。

运行的具体流程是:主线程调用线程池创建函数,所有工作线程处于等待信号的blocked的状态;主线程得到新任务,调用线程池的doWork函数将任务放入内部队列中,同时发出唤醒信号;其中一个工作线程被唤醒,利用函数指针disposer所指向的函数处理任务;任务处理完成后重新进入等待状态。(也可以让线程池内部维护一个线程状态的数组,每次有新任务,就检查这个数组,找出空闲的线程)

 以上是一个很标准的实现。但是在实现中也遇到了一些问题,比如说用signal好还是用broadcast好,后来认为broadcast会带来不必要的contention,所以没用。在测试的时候发现,当任务数量很少的时候几乎是同一个线程每次都拿到任务,而其他的线程都starve了(这个还没想清楚为什么);后来发现当任务多的时候,其他的线程还是有很多机会拿到任务的;同时发现printf会极大的影响多线程任务的输出结果,测试的时候还是多把stdout 重定向到一个文件当中比较好。

线程池的变形也有很多,其中比较著名的是Leader/Follower模式。这个模型进一步节省了主线程(Leader)给工作线程(Follower)分配工作的开销 (之前的模型可以叫做Boss/Worker模型)。 主要的思想就是线程池的线程中有一个是Leader,Leader每次拿到任务后不再分配,而是把自己变成follower,然后处理这个任务,同时再选出一个空闲线程作为Leader继续等待任务,这样就节省了Boss和worker之间的任务分配(找出空闲线程)和不必要的数据拷贝。(以后有机会就实现一下这个模型,可能还会遇到一些具体的问题。)

三个原语基本介绍完了,以后可能还会发现更多的原语,但是这三个原语基本上可以构成一个软件的核心了。对于数据处理型软件,第一步就是获得数据,通常是网络,所以处于最前端的是I/O模型,优秀的I/O模型能够高效的实现海量连接。同时处理I/O的线程也就成为了producer,这些数据被放入queue中等待多个consumer的处理,这里就是线程模型。为了高效的处理任务,在consumer一端通常使用线程池。所以,这几个原语是密不可分,相辅相成的(怎么读起来像中学政治教材。。。)。

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: