原文链接--http://blog.sina.com.cn/s/blog_7011f21c0101dkjj.html
在OC的框架中从NSOperation到GCD的dispatch queue到处都充斥着队列的概念,OC的框架帮我们把底层线程的调度都已经写好了,这样的好处是我们可以专心于上层的业务逻辑,坏处当然是我们对底层调度的掌控力变弱了。写这个线程池的原因也是练练手,至于效率如何,在发到线上几个版本后,反馈还可以。当然还有空间可以持续优化。
一.线程池流程
1.在程序启动时创建固定个线程,做为线程池,等待调度
2.当线程池获取到任务时 根据任务类型进行线程调度
3.任务执行
整个的流程很简单,下面我们需要创建一些必要的结构来支持我们的需求
typedef void (*tfmethod)(void *,short *);
typedef struct s_tftask_content{
tfmethod method;
void *arg;
short *cancel_point;
struct s_tftask_content *next;
}s_tftask_content;
typedef struct s_tfthread_config{
pthread_mutex_t mtx;
pthread_cond_t cond;
}s_tfthread_config;
typedef struct s_tftask{
s_tfthread_config config;
short thread_status;
s_tftask_content *task_list;
}s_tftask;
enum tfthread_status{
tfthread_init=0x0,
tfthread_idle,
tfthread_inuse,
tfthread_dead
};
enum tftask_type{
tftask_net_req=0x0,
tftask_first_respond,
tftask_assign,
tftask_io_write
};
typedef struct s_tfthread{
s_tftask *tftask;
char *name;
}s_tfthread;
二.实现
1.循环通过pthread_create创建线程,创建s_tfthread对象做为线程句柄加入线程数组,s_tftask_content->methord初始化为空函数,同时创建任务执行函数,执行完task初始化函数后,在执行函数中通过pthread_cond_wait信号将当前创建的线程挂起。
s_tftask_content *content = (s_tftask_content *)malloc(sizeof(s_tftask_content));
content->next= NULL;
content->method = empty_run;
content->cancel_point=NULL;
s_tftask *task = (s_tftask *)malloc(sizeof(s_tftask));
task->task_list = content;
task->thread_status = tfthread_idle;
s_tfthread_config config = {PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER};
task->config = config;
s_tfthread *thread = (s_tfthread *)malloc(sizeof(s_tfthread));
thread->tftask = task;
thread->name = k_tfthread_names[i];
k_threads[i]=thread;
ret = pthread_create(&posix_t_id, &attr, tfthreadpool_task_run,task);
2.循环创建完毕之后,程序中将会有n个挂起状态的线程,当需要执行新的task的时候查找根据不同的task标志在k_threads中查询出空闲线程,并创建新的s_tftask_content加入s_tfthread的任务列表,通过pthread_cond_signal重新唤醒该线程继续执行任务。