热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Linux下C语言线程池实现

0x00前言文章中的文字可能存在语法错误以及标点错误,请谅解;如果在文章中发现代码错误或其它问题请告知,感谢!0x01

0x00前言

文章中的文字可能存在语法错误以及标点错误,请谅解;

如果在文章中发现代码错误或其它问题请告知,感谢!

0x01线程池工作原理简介

线程池是一个比较抽象的概念,其包含任务队列,多个线程,管理线程等。

在应用程序启动后,线程池首先会创建一定数量的线程,放入到空闲队列,并让所有线程处在阻塞状态 。当有任务发生后,线程池会选择一个空闲的线程,将任务传入到该线程运行。执行完任务之后,线程并不退出,而是继续在线程池中阻塞等待下一次的任务。

当线程池中所有的线程处在执行任务时,线程池将自动创建一定数量的新线程,以便处理新的任务。

当线程池中大部分线程处在阻塞态时,线程池会自动销毁一部分线程,以便节约资源。

下图是线程池工作示意图:
在这里插入图片描述

0x02 为什么使用线程池

1.减少因频繁创建以及销毁线程产生的系统开销。
大多数网络服务器的特点就是单位时间内处理数量巨大的连接请求。这些请求的处理时间通常比较短(线程创建时间T1,请求处理时间T2,销毁线程时间T3,T2

2.避免线程并发数量过多导致抢占系统资源从而导致阻塞情况

若执行的线程过多,会导致系统资源不足产生的阻塞情况。使用线程池可以有效控制上述情况。

3.对线程进行一些简单的管理

对线程的延时、定时循环等策略可以进行很好的实现。

0x03线程池代码实现

下面的各部分代码块中都有注释,可以参考注释理解线程池的工作原理,相关联的功能函数放在了一个代码块中。0x04小节最后有完整代码的GitHub下载路径。

1.线程池总结构体tp_thread_pool_s以及每个线程信息结构体
tp_thread_info_s中包含线程的状态例如是否被占用、可以被调用等。
tp_thread_pool_sl 中包含线程池的状态信息,包括多个函数指针,作用为执行对应的初始化函数、线程关闭函数、任务处理函数等。

//线程信息结构体
struct tp_thread_info_s{int is_busy; //线程是否忙碌int is_wait; //线程是否可以被调用int is_signal; //线程是否收到条件变量int is_destroy; //线程是否被销毁void (*func)(void *);void *input;void *output;pthread_cond_t thread_cond;pthread_mutex_t thread_lock;pthread_t thread_id; //线程ID
};

//线程池结构
struct tp_thread_pool_s{int (*init)(tp_thread_pool *this); //指向init函数的指针,下同void (*close)(tp_thread_pool *this);int (*process_job)(tp_thread_pool *this, void(*func)(void* input), void * input ,void *output);int (*get_thread_by_id)(tp_thread_pool *this, pthread_t id);int (*add_thread)(tp_thread_pool *this);int (*delete_thread)(tp_thread_pool *this);int (*get_tp_status)(tp_thread_pool *this);int min_th_num; //线程池中线程最小数量int cur_th_num; //当前线程池数量int max_th_num; //线程池中线程最大数量pthread_mutex_t tp_lock;pthread_t manage_thread_id; //管理线程的IDtp_thread_info *thread_info; //工作线程的相关信息
};
tp_thread_pool * pool;

2.线程池的创建及初始化。
线程池的创建过程以及初始化过程,参照注释理解。

//线程池创造以及初始化
int thread_pool_init(int min_num,int max_num)
{pool = creat_thread_pool(min_num,max_num); //创造线程池if(tp_init(pool)==FALSE) //初始化线程池{printf("Thread Pool : tp_init is wrong!\n");return TRUE;}return FALSE;
}

//创造线程池
tp_thread_pool *creat_thread_pool(int min_num, int max_num)
{tp_thread_pool *this; //有关线程池操作的接口信息this = (tp_thread_pool*)malloc(sizeof(tp_thread_pool));memset(this, 0, sizeof(tp_thread_pool));//初始化指向各功能函数this->init = tp_init;this->close = tp_close;this->process_job = tp_process_job;this->get_thread_by_id = tp_get_thread_by_id;this->add_thread = tp_add_thread;this->delete_thread = tp_delete_thread;this->get_tp_status = tp_get_tp_status;this->min_th_num = min_num; //最小线程数量this->cur_th_num = this->min_th_num; //当前线程数量this->max_th_num = max_num; //最大线程数量pthread_mutex_init(&this->tp_lock, NULL);if(NULL != this->thread_info)free(this->thread_info);this->thread_info = (tp_thread_info*)malloc(sizeof(tp_thread_info)*this->max_th_num); //申请max_th_num个相关线程信息内存空间return this;
}

对于线程池的初始化,可以参考如下示意图:
在这里插入图片描述

//线程池初始化
int tp_init(tp_thread_pool *this)
{int i;int err;for(i=0;imin_th_num;i++) //创建min_th_num个线程{//线程池各个线程的信息初始化pthread_cond_init(&this->thread_info[i].thread_cond, NULL); //为每个线程的条件变量初始化pthread_mutex_init(&this->thread_info[i].thread_lock, NULL); //为每个线程上锁this->thread_info[i].is_signal = FALSE;this->thread_info[i].is_wait = FALSE;this->thread_info[i].is_busy = FALSE;this->thread_info[i].is_destroy = FALSE;err = pthread_create(&this->thread_info[i].thread_id, NULL, tp_work_thread, this); //创建工作线程,见5if(0 != err){printf("Thread Pool : creat work thread failed when init\n");return FALSE;}}err = pthread_create(&this->manage_thread_id, NULL, tp_manage_thread, this); //创建管理线程,见4if(0 != err){printf("Thread Pool : creat manage thread failed\n");return FALSE;}return TRUE;
}

3.线程池释放。
当线程池使用完毕,线程池的销毁过程。

//销毁线程池
void tp_close(tp_thread_pool *this)
{int i;for(i=0;icur_th_num;i++){//销毁线程池中当前所有线程//pthread_kill(this->thread_info[i].thread_id, SIGKILL);pthread_cancel(this->thread_info[i].thread_id);pthread_mutex_destroy(&this->thread_info[i].thread_lock);pthread_cond_destroy(&this->thread_info[i].thread_cond);}//销毁管理线程//pthread_kill(this->manage_thread_id, SIGKILL);pthread_cancel(this->manage_thread_id);pthread_mutex_destroy(&this->tp_lock);printf("tp_close: kill manage thread %lu\n", this->manage_thread_id);free(this->thread_info);

4.管理线程。
获得当前线程池状态信息,检查是否需要销毁部分空闲线程,以便回收系统资源。

//管理线程,监测是否需要销毁部分空闲线程
void *tp_manage_thread(void *pthread)
{tp_thread_pool *this = (tp_thread_pool*)pthread;pthread_detach(pthread_self());sleep(MANAGE_INTERVAL);printf("Thread Pool : tp_manage_thread(%d/%d/%d) .\n", this->min_th_num, this->cur_th_num, this->max_th_num); //当程池中的最小、当前、最大线程数量do{printf("Thread Pool : manage_thread do\n");if( this->get_tp_status(this) == 0 ) //获得当前线程池状态信息,检查是否需要销毁部分空闲线程。返回0需要销毁一部分空闲线程,1不销毁{printf("Thread Pool : manage_thread begin to delete.\n");do{if( !this->delete_thread(this) ) //{printf("Thread Pool : manage_thread delete done.\n");break;}}while(TRUE);}sleep(MANAGE_INTERVAL);}while(TRUE);pthread_exit(NULL);
}

//获得线程池信息,检查是否需要销毁部分空闲线程,回收系统资源
int tp_get_tp_status(tp_thread_pool *this)
{int busy_num = 0;int i;for(i=0;icur_th_num;i++) //查看当前线程池线程中的工作线程数量{if(this->thread_info[i].is_busy)busy_num++;}printf("Thread Pool : get_tp_status(%d/%d/%d)(busy %d) .\n", this->min_th_num, this->cur_th_num, this->max_th_num, busy_num);if(busy_num/(this->cur_th_num) cur_th_num);return FALSE;}else{printf("Thread Pool : get_tp_status(%d/%d) not to delete.\n", busy_num, this->cur_th_num);return TRUE;}
}

//线程池销毁线程,从编号最后的、空闲的线程开始销毁
int tp_delete_thread(tp_thread_pool *this)
{int ret &#61; 0;int i &#61; 0;int waitloop &#61; 0;pthread_mutex_lock(&this->tp_lock);if(this->cur_th_num <&#61; this->min_th_num) //若当前线程数量小于线程池最小数量&#xff0c;无需销毁线程{pthread_mutex_unlock(&this->tp_lock);printf("Thread Pool : No need to delete thread!\n");return FALSE;}i &#61; this->cur_th_num - 1;pthread_mutex_lock(&this->thread_info[i].thread_lock); //为线程池中编号最后的、空闲的线程上锁if(this->thread_info[i].is_busy) //若该线程在工作&#xff0c;解锁{pthread_mutex_unlock(&this->thread_info[i].thread_lock);pthread_mutex_unlock(&this->tp_lock);printf("Thread Pool : delete the last thread(%d) busy.\n", (i&#43;1));return FALSE;}//删除该空闲线程操作this->thread_info[i].is_busy &#61; FALSE;this->thread_info[i].func &#61; (void (*)(void *))tp_doNothing_forDelete; //将当前线程指向tp_work_thread func函数//(void (*)(void *)):函数返回值数据类型 &#xff08;*指针变量名&#xff09;&#xff08;函数的实际参数或者函数参数的类型&#xff09;this->thread_info[i].input &#61; this; //tp_work_thread input参数pthread_cond_signal(&this->thread_info[i].thread_cond); //向tp_work_thread的thread_cond发信号printf("Thread Pool : delete thread %d, cur num: %d, wait: %d, signal: %d, busy: %d\n",(i&#43;1), this->cur_th_num, this->thread_info[i].is_wait, this->thread_info[i].is_signal, this->thread_info[i].is_busy);pthread_mutex_unlock(&this->thread_info[i].thread_lock); //解锁当前线程while (this->thread_info[i].is_destroy !&#61; TRUE) //为该线程等待一段时间{usleep(10000);waitloop&#43;&#43;;if (waitloop >&#61; 100){break;}}ret &#61; pthread_mutex_destroy(&this->thread_info[i].thread_lock); //销毁当前线程互斥锁if (0 !&#61; ret){printf("Thread Pool : mutex destroy failed (ret %d) on thread %d (waitloop %d).\n", ret, (i&#43;1), waitloop);}ret &#61; pthread_cond_destroy(&this->thread_info[i].thread_cond); //销毁当前线程条件变量if (0 !&#61; ret){printf("Thread Pool : cond destroy failed (ret %d) on thread %d (waitloop %d).\n", ret, (i&#43;1), waitloop);}//ret &#61; pthread_kill(this->thread_info[this->cur_th_num-1].thread_id, SIGKILL);ret &#61; pthread_cancel(this->thread_info[i].thread_id); //申请销毁线程if (0 !&#61; ret){printf("Thread Pool : cancel failed (ret %d) on thread %d (waitloop %d).\n", ret, (i&#43;1), waitloop);}this->cur_th_num--; //销毁了一个线程&#xff0c;使得当前线程池线程数量减1pthread_mutex_unlock(&this->tp_lock);printf("Thread Pool : cancel success thread %d, cur num %d (waitloop %d)!\n", (i&#43;1), this->cur_th_num, waitloop);return TRUE;
}

//删除操作
void tp_doNothing_forDelete(tp_thread_pool *this)
{int waitLoop &#61; 0;if (NULL &#61;&#61; this){printf("Thread Pool : delete thread FAIL because of NULL!\n");return;}this->thread_info[this->cur_th_num-1].is_destroy &#61; TRUE;//查看该线程&#xff08;编号最后一个线程&#xff09;是否销毁printf("Thread Pool : tp_delete_thread set destory %d TRUE. \n", (this->cur_th_num));while (1){usleep(10000);waitLoop&#43;&#43;;if (waitLoop >&#61; 1000){break;}}this->thread_info[this->cur_th_num-1].is_destroy &#61; FALSE; //查看该线程&#xff08;编号最后一个线程&#xff09;是否销毁printf("Thread Pool : delete thread %d FAIL because of timeout!\n", (this->cur_th_num));return;
}

5.工作线程
工作线程逻辑示意图&#xff1a;
在这里插入图片描述

//工作线程
void *tp_work_thread(void *pthread)
{pthread_t curid;int nseq;tp_thread_pool *this &#61; (tp_thread_pool*)pthread;curid &#61; pthread_self(); //获得该线程自身IDnseq &#61; this->get_thread_by_id(this, curid); //返回该线程在线程池中的队列编号pthread_detach(pthread_self());if(nseq <0){printf("Thread Pool : work thread(ID %d / curid %d) is wrong.\n", nseq&#43;1, (int)curid);pthread_exit(NULL);}while(TRUE){pthread_mutex_lock(&this->thread_info[nseq].thread_lock); //在线程池中对编号为nseq线程加锁this->thread_info[nseq].is_wait &#61; TRUE; //设置为真&#xff0c;等待被调用do{printf("Thread Pool : tp_work_thread begin wait id: %d, wait: %d, signal: %d, busy: %d\n",(nseq &#43; 1), this->thread_info[nseq].is_wait, this->thread_info[nseq].is_signal, this->thread_info[nseq].is_busy);pthread_cond_wait(&this->thread_info[nseq].thread_cond, &this->thread_info[nseq].thread_lock); //挂起该线程printf("Thread Pool : tp_work_thread after wait id: %d, wait: %d, signal: %d, busy: %d\n",(nseq &#43; 1), this->thread_info[nseq].is_wait, this->thread_info[nseq].is_signal, this->thread_info[nseq].is_busy);}while((this->thread_info[nseq].is_signal) !&#61; TRUE); //挂起该线程&#xff0c;等待信号this->thread_info[nseq].is_busy &#61; TRUE; //被唤醒后&#xff0c;该线程为工作状态this->thread_info[nseq].is_wait &#61; FALSE; //表示不能被调用this->thread_info[nseq].is_signal &#61; FALSE; //没有收到signal_cond信号printf("Thread Pool : tp_work_thread got signal (%d/%d) busy %d.\n", (nseq &#43; 1), this->cur_th_num, this->thread_info[nseq].is_busy);pthread_mutex_unlock(&this->thread_info[nseq].thread_lock);printf("Thread Pool : tp_work_thread got signal unlock(%d/%d) busy %d.\n", (nseq &#43; 1), this->cur_th_num, this->thread_info[nseq].is_busy);(*(this->thread_info[nseq].func))(this->thread_info[nseq].input); //执行用户定义的函数func以及参数input&#xff0c;直至退出printf("Thread Pool : the callback return(%d/%d).\n", (nseq &#43; 1), this->cur_th_num);pthread_mutex_lock(&this->thread_info[nseq].thread_lock);this->thread_info[nseq].is_busy &#61; FALSE; //表示该线程现在处于空闲状态pthread_mutex_unlock(&this->thread_info[nseq].thread_lock);printf("Thread Pool : set free (%d/%d) after the callback return.\n", (nseq &#43; 1), this->cur_th_num);}
}

6.为消息分类处理函数寻找空闲线程
对于tp_process_job&#xff08;&#xff09;的理解&#xff0c;可以参考下面的逻辑示意图&#xff1a;

在这里插入图片描述

//对外接口
int tp_process_job(tp_thread_pool *this, void(*pFunc)(void*), void *pInput ,void *pOutput)
{int i;int waitLoop &#61; 0;printf("Thread Pool : tp_process_job(%d/%d/%d).\n", this->min_th_num, this->cur_th_num, this->max_th_num);for (i &#61; 0; i cur_th_num; i&#43;&#43;){printf("Thread Pool : tp_process_job for(%d/%d).\n", i&#43;1, this->cur_th_num);pthread_mutex_lock(&this->thread_info[i].thread_lock); //从队列中0开始找&#xff0c;上锁printf("Thread Pool : tp_process_job get lock(%d/%d).\n", i&#43;1, this->cur_th_num);if(!this->thread_info[i].is_busy) //寻找在线程池中空闲线程{printf("Thread Pool : tp_process_job get free(%d/%d).\n", i&#43;1, this->cur_th_num);this->thread_info[i].is_busy &#61; TRUE; //找到空闲线程后&#xff0c;设置该线程为忙碌if(this->thread_info[i].is_wait !&#61; TRUE) //判断该线程是否能够被调用{printf("Thread Pool : tp_process_job wait fail. id : %d, all num : %d, wait : %d, busy : %d, signal : %d.\n",i&#43;1, this->cur_th_num, this->thread_info[i].is_wait, this->thread_info[i].is_busy, this->thread_info[i].is_signal);this->thread_info[i].is_busy &#61; FALSE; //若该线程不能别调用将该标志位恢复原来的状态pthread_mutex_unlock(&this->thread_info[i].thread_lock);return 1; //失败返回}else{this->thread_info[i].is_signal &#61; TRUE; //设置该线程收到cond_signal信号this->thread_info[i].func &#61; pFunc; //函数指针指向消息分类处理函数this->thread_info[i].input &#61; pInput; //指向消息分类函数输入参数this->thread_info[i].output &#61; pOutput; //指向消息分类函数输出参数pthread_cond_signal(&this->thread_info[i].thread_cond); //唤醒该线程&#xff08;tp_work_thread&#xff09;this->thread_info[i].is_busy &#61; FALSE;printf("Thread Pool : tp_process_job send signal. id : %d, all num : %d, wait : %d, busy : %d, signal : %d.\n",i&#43;1, this->cur_th_num, this->thread_info[i].is_wait, this->thread_info[i].is_busy, this->thread_info[i].is_signal);pthread_mutex_unlock(&this->thread_info[i].thread_lock);return 0;}}else{pthread_mutex_unlock(&this->thread_info[i].thread_lock);}}//若线程池中当前所有线程都忙碌&#xff08;thread_info[i].is_busy &#61;&#61; TRUE&#xff09;&#xff0c;则在线程池中新加一个线程并使用pthread_mutex_lock(&this->tp_lock); //对线程池上锁if(this->add_thread(this)) //若添加线程成功{i &#61; this->cur_th_num - 1; //cur_th_num在add_thread已经加1&#xff0c;为了显示正确的线程队列位置i&#xff0c;减1printf("Thread Pool : add new one. id : %d, all num : %d.\n", i&#43;1, this->cur_th_num);pthread_mutex_unlock(&this->tp_lock);waitLoop &#61; 0;while (this->thread_info[i].is_wait !&#61; TRUE) //判断该线程是否能够被调用{usleep(1000); //等待waitLoop&#43;&#43;;if (waitLoop >&#61; 10){break;}}pthread_mutex_lock(&this->thread_info[i].thread_lock);if (waitLoop >&#61; 10) //若规定的时间结束仍不能被调用{this->thread_info[i].is_busy &#61; FALSE; //将线程设置为空闲printf("Thread Pool : tp_process_job add waitloop fail. id : %d, all num : %d, waitLoop : %d, wait : %d, busy : %d, signal : %d.\n",i&#43;1, this->cur_th_num, waitLoop, this->thread_info[i].is_wait, this->thread_info[i].is_busy, this->thread_info[i].is_signal);pthread_mutex_unlock(&this->thread_info[i].thread_lock);return 1;}else{//同上this->thread_info[i].is_signal &#61; TRUE;this->thread_info[i].is_busy &#61; FALSE;this->thread_info[i].func &#61; pFunc;this->thread_info[i].input &#61; pInput;this->thread_info[i].output &#61; pOutput;pthread_cond_signal(&this->thread_info[i].thread_cond);printf("Thread Pool : tp_process_job add send signal. id : %d, all num : %d, waitLoop : %d, wait : %d, busy : %d, signal : %d.\n",i&#43;1, this->cur_th_num, waitLoop, this->thread_info[i].is_wait, this->thread_info[i].is_busy, this->thread_info[i].is_signal);pthread_mutex_unlock(&this->thread_info[i].thread_lock);}}else{pthread_mutex_unlock(&this->tp_lock);printf("Thread Pool : add new failed!\n");return TRUE;}return FALSE;
}

//增加一个新的线程
int tp_add_thread(tp_thread_pool *this)
{int err;tp_thread_info *new_thread; //新建一个线程属性if(this->max_th_num <&#61; this->cur_th_num) //若新建了一个线程之后&#xff0c;当前线程数超过线程池最大线程数则返回0{printf("Thread Pool : The thread poor is full(%d/%d).\n", this->cur_th_num, this->max_th_num);return FALSE;}new_thread &#61; &this->thread_info[this->cur_th_num]; //将新建线程插入到线程池队列//互斥锁和条件变量等初始化err &#61; pthread_cond_init(&new_thread->thread_cond, NULL);if (0 !&#61; err){printf("Thread Pool : add cond_init ret %d, all: %d\n", err, this->cur_th_num);return FALSE;}err &#61; pthread_mutex_init(&new_thread->thread_lock, NULL);if (0 !&#61; err){printf("Thread Pool : add mutex_init ret %d, all: %d\n", err, this->cur_th_num);return FALSE;}new_thread->is_signal &#61; FALSE;new_thread->is_wait &#61; FALSE;new_thread->is_destroy &#61; FALSE;new_thread->is_busy &#61; TRUE;this->cur_th_num &#61; this->cur_th_num &#43; 1; //将当前线程数量加1err &#61; pthread_create(&new_thread->thread_id, NULL, tp_work_thread, this); //创建新工作线程tp_work_threadif(0 !&#61; err) //若失败&#xff0c;将当前线程数量减1恢复原数量{printf("Thread Pool : create new thread failed.\n");this->cur_th_num &#61; this->cur_th_num - 1;return FALSE;}return TRUE;
}

0x04运行结果

代码完成后&#xff0c;编写一个程序运行脚本make.sh&#xff0c;方便编译&#xff1a;

gcc -o ThreadTest *.c -lpthread

整个工程目录&#xff1a;
在这里插入图片描述

在终端上输入make.sh生成可执行文件并运行&#xff0c;运行结果部分截图&#xff1a;
在这里插入图片描述
完整的运行结果&#xff1a;

fip&#64;ubuntu:~/Desktop/server$ ./ThreadTest
Thread Pool : tp_work_thread begin wait id: 1, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 2, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 3, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 4, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 5, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 6, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 7, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 8, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 9, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 10, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 11, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 12, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 13, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 14, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 15, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 16, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 17, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 18, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 20, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 19, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 22, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 21, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 25, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 23, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 27, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 24, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 26, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 28, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 32, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 33, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 30, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 31, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 29, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 35, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 34, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 39, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 49, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 41, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 48, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 146, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 166, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 52, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 36, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 37, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 43, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 57, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 115, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 160, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 172, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 88, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 38, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 51, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 71, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 72, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 77, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 103, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 116, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 155, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 40, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 81, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 42, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 85, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 112, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 171, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 120, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 44, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 62, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 74, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 104, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 174, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 100, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 130, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 56, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 46, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 55, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 45, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 53, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 65, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 68, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 98, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 137, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 47, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 50, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 59, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 60, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 61, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 63, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 67, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 79, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 82, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 84, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 95, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 101, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 119, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 121, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 135, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 159, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 169, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 168, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 54, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 73, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 110, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 94, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 124, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 58, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 70, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 141, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 64, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 87, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 136, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 156, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 175, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 69, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 80, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 139, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 158, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 102, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 66, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 76, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 78, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 157, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 86, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 89, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 144, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 173, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 118, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 90, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 91, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 93, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 96, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 114, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 75, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 83, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 107, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 111, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 113, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 125, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 132, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 143, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 145, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 151, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 167, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 170, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 106, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 92, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 99, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 109, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 122, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 123, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 131, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 149, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 154, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 163, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 164, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 97, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 126, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 127, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 128, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 117, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 105, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 134, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 162, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 108, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 129, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 147, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 165, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 138, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 140, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 150, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 133, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 142, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 152, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 161, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 153, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 148, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 176, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 177, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 178, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 179, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 180, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 181, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 182, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 183, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 184, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 185, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 186, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 187, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 188, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 189, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 190, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 191, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 192, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 193, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 194, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 195, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 196, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 197, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 198, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 199, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 200, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 201, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 202, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 203, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 204, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 205, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 207, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 208, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 209, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 210, wait: 1, signal: 0, busy: 0
Thread Pool : tp_process_job(300/300/500).
Thread Pool : tp_process_job for(1/300).
Thread Pool : tp_process_job get lock(1/300).
Thread Pool : tp_process_job get free(1/300).
Thread Pool : tp_process_job send signal. id : 1, all num : 300, wait : 1, busy : 0, signal : 1.
Thread Pool : tp_work_thread after wait id: 1, wait: 1, signal: 1, busy: 0
Thread Pool : tp_work_thread got signal (1/300) busy 1.
Thread Pool : tp_work_thread got signal unlock(1/300) busy 1.
threadpoolp callback fuction : 1.
Thread Pool : tp_process_job(300/300/500).
Thread Pool : tp_process_job for(1/300).
Thread Pool : tp_process_job get lock(1/300).
Thread Pool : tp_process_job for(2/300).
Thread Pool : tp_process_job get lock(2/300).
Thread Pool : tp_process_job get free(2/300).
Thread Pool : tp_process_job send signal. id : 2, all num : 300, wait : 1, busy : 0, signal : 1.
Thread Pool : tp_work_thread after wait id: 2, wait: 1, signal: 1, busy: 0
Thread Pool : tp_work_thread got signal (2/300) busy 1.
Thread Pool : tp_work_thread got signal unlock(2/300) busy 1.
threadpoolp callback fuction : 2.
Thread Pool : tp_process_job(300/300/500).
Thread Pool : tp_process_job for(1/300).
Thread Pool : tp_process_job get lock(1/300).
Thread Pool : tp_process_job for(2/300).
Thread Pool : tp_process_job get lock(2/300).
Thread Pool : tp_process_job for(3/300).
Thread Pool : tp_process_job get lock(3/300).
Thread Pool : tp_process_job get free(3/300).
Thread Pool : tp_process_job send signal. id : 3, all num : 300, wait : 1, busy : 0, signal : 1.
Thread Pool : tp_work_thread after wait id: 3, wait: 1, signal: 1, busy: 0
Thread Pool : tp_work_thread got signal (3/300) busy 1.
Thread Pool : tp_work_thread got signal unlock(3/300) busy 1.
threadpoolp callback fuction : 3.
Thread Pool : tp_process_job(300/300/500).
Thread Pool : tp_process_job for(1/300).
Thread Pool : tp_process_job get lock(1/300).
Thread Pool : tp_process_job for(2/300).
Thread Pool : tp_process_job get lock(2/300).
Thread Pool : tp_process_job for(3/300).
Thread Pool : tp_process_job get lock(3/300).
Thread Pool : tp_process_job for(4/300).
Thread Pool : tp_process_job get lock(4/300).
Thread Pool : tp_process_job get free(4/300).
Thread Pool : tp_process_job send signal. id : 4, all num : 300, wait : 1, busy : 0, signal : 1.
Thread Pool : tp_work_thread after wait id: 4, wait: 1, signal: 1, busy: 0
Thread Pool : tp_work_thread got signal (4/300) busy 1.
Thread Pool : tp_work_thread got signal unlock(4/300) busy 1.
threadpoolp callback fuction : 4.
Thread Pool : tp_process_job(300/300/500).
Thread Pool : tp_process_job for(1/300).
Thread Pool : tp_process_job get lock(1/300).
Thread Pool : tp_process_job for(2/300).
Thread Pool : tp_process_job get lock(2/300).
Thread Pool : tp_process_job for(3/300).
Thread Pool : tp_process_job get lock(3/300).
Thread Pool : tp_process_job for(4/300).
Thread Pool : tp_process_job get lock(4/300).
Thread Pool : tp_process_job for(5/300).
Thread Pool : tp_process_job get lock(5/300).
Thread Pool : tp_process_job get free(5/300).
Thread Pool : tp_process_job send signal. id : 5, all num : 300, wait : 1, busy : 0, signal : 1.
Thread Pool : tp_work_thread after wait id: 5, wait: 1, signal: 1, busy: 0
Thread Pool : tp_work_thread got signal (5/300) busy 1.
Thread Pool : tp_work_thread got signal unlock(5/300) busy 1.
threadpoolp callback fuction : 5.
Thread Pool : tp_process_job(300/300/500).
Thread Pool : tp_process_job for(1/300).
Thread Pool : tp_process_job get lock(1/300).
Thread Pool : tp_process_job for(2/300).
Thread Pool : tp_process_job get lock(2/300).
Thread Pool : tp_process_job for(3/300).
Thread Pool : tp_process_job get lock(3/300).
Thread Pool : tp_process_job for(4/300).
Thread Pool : tp_process_job get lock(4/300).
Thread Pool : tp_process_job for(5/300).
Thread Pool : tp_process_job get lock(5/300).
Thread Pool : tp_process_job for(6/300).
Thread Pool : tp_process_job get lock(6/300).
Thread Pool : tp_process_job get free(6/300).
Thread Pool : tp_process_job send signal. id : 6, all num : 300, wait : 1, busy : 0, signal : 1.
Thread Pool : tp_work_thread after wait id: 6, wait: 1, signal: 1, busy: 0
Thread Pool : tp_work_thread got signal (6/300) busy 1.
Thread Pool : tp_work_thread got signal unlock(6/300) busy 1.
threadpoolp callback fuction : 6.
Thread Pool : tp_process_job(300/300/500).
Thread Pool : tp_process_job for(1/300).
Thread Pool : tp_process_job get lock(1/300).
Thread Pool : tp_process_job for(2/300).
Thread Pool : tp_process_job get lock(2/300).
Thread Pool : tp_process_job for(3/300).
Thread Pool : tp_process_job get lock(3/300).
Thread Pool : tp_process_job for(4/300).
Thread Pool : tp_process_job get lock(4/300).
Thread Pool : tp_process_job for(5/300).
Thread Pool : tp_process_job get lock(5/300).
Thread Pool : tp_process_job for(6/300).
Thread Pool : tp_process_job get lock(6/300).
Thread Pool : tp_process_job for(7/300).
Thread Pool : tp_process_job get lock(7/300).
Thread Pool : tp_process_job get free(7/300).
Thread Pool : tp_process_job send signal. id : 7, all num : 300, wait : 1, busy : 0, signal : 1.
Thread Pool : tp_work_thread after wait id: 7, wait: 1, signal: 1, busy: 0
Thread Pool : tp_work_thread got signal (7/300) busy 1.
Thread Pool : tp_work_thread got signal unlock(7/300) busy 1.
threadpoolp callback fuction : 7.
Thread Pool : tp_process_job(300/300/500).
Thread Pool : tp_process_job for(1/300).
Thread Pool : tp_process_job get lock(1/300).
Thread Pool : tp_process_job for(2/300).
Thread Pool : tp_process_job get lock(2/300).
Thread Pool : tp_process_job for(3/300).
Thread Pool : tp_process_job get lock(3/300).
Thread Pool : tp_process_job for(4/300).
Thread Pool : tp_process_job get lock(4/300).
Thread Pool : tp_process_job for(5/300).
Thread Pool : tp_process_job get lock(5/300).
Thread Pool : tp_process_job for(6/300).
Thread Pool : tp_process_job get lock(6/300).
Thread Pool : tp_process_job for(7/300).
Thread Pool : tp_process_job get lock(7/300).
Thread Pool : tp_process_job for(8/300).
Thread Pool : tp_process_job get lock(8/300).
Thread Pool : tp_process_job get free(8/300).
Thread Pool : tp_process_job send signal. id : 8, all num : 300, wait : 1, busy : 0, signal : 1.
Thread Pool : tp_work_thread after wait id: 8, wait: 1, signal: 1, busy: 0
Thread Pool : tp_work_thread got signal (8/300) busy 1.
Thread Pool : tp_work_thread got signal unlock(8/300) busy 1.
threadpoolp callback fuction : 8.
Thread Pool : tp_process_job(300/300/500).
Thread Pool : tp_process_job for(1/300).
Thread Pool : tp_process_job get lock(1/300).
Thread Pool : tp_process_job for(2/300).
Thread Pool : tp_process_job get lock(2/300).
Thread Pool : tp_process_job for(3/300).
Thread Pool : tp_process_job get lock(3/300).
Thread Pool : tp_process_job for(4/300).
Thread Pool : tp_process_job get lock(4/300).
Thread Pool : tp_process_job for(5/300).
Thread Pool : tp_process_job get lock(5/300).
Thread Pool : tp_process_job for(6/300).
Thread Pool : tp_process_job get lock(6/300).
Thread Pool : tp_process_job for(7/300).
Thread Pool : tp_process_job get lock(7/300).
Thread Pool : tp_process_job for(8/300).
Thread Pool : tp_process_job get lock(8/300).
Thread Pool : tp_process_job for(9/300).
Thread Pool : tp_process_job get lock(9/300).
Thread Pool : tp_process_job get free(9/300).
Thread Pool : tp_process_job send signal. id : 9, all num : 300, wait : 1, busy : 0, signal : 1.
Thread Pool : tp_process_job(300/300/500).
Thread Pool : tp_process_job for(1/300).
Thread Pool : tp_process_job get lock(1/300).
Thread Pool : tp_process_job for(2/300).
Thread Pool : tp_process_job get lock(2/300).
Thread Pool : tp_process_job for(3/300).
Thread Pool : tp_process_job get lock(3/300).
Thread Pool : tp_process_job for(4/300).
Thread Pool : tp_process_job get lock(4/300).
Thread Pool : tp_process_job for(5/300).
Thread Pool : tp_process_job get lock(5/300).
Thread Pool : tp_process_job for(6/300).
Thread Pool : tp_process_job get lock(6/300).
Thread Pool : tp_process_job for(7/300).
Thread Pool : tp_process_job get lock(7/300).
Thread Pool : tp_process_job for(8/300).
Thread Pool : tp_process_job get lock(8/300).
Thread Pool : tp_process_job for(9/300).
Thread Pool : tp_process_job get lock(9/300).
Thread Pool : tp_process_job get free(9/300).
Thread Pool : tp_process_job send signal. id : 9, all num : 300, wait : 1, busy : 0, signal : 1.
Thread Pool : tp_work_thread begin wait id: 212, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread after wait id: 9, wait: 1, signal: 1, busy: 0
Thread Pool : tp_work_thread got signal (9/300) busy 1.
Thread Pool : tp_work_thread got signal unlock(9/300) busy 1.
threadpoolp callback fuction : 10.
Thread Pool : tp_work_thread begin wait id: 213, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 214, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 215, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 216, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 217, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 218, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 219, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 220, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 221, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 222, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 223, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 224, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 225, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 226, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 227, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 228, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 229, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 230, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 231, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 232, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 233, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 234, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 235, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 236, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 237, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 238, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 239, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 240, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 241, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 242, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 243, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 244, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 245, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 246, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 247, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 248, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 249, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 250, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 251, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 252, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 253, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 254, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 206, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 255, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 256, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 257, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 258, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 259, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 260, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 261, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 262, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 263, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 264, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 265, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 266, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 267, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 268, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 269, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 270, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 271, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 272, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 273, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 274, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 275, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 276, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 277, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 278, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 279, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 280, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 281, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 282, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 283, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 284, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 285, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 286, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 290, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 287, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 289, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 291, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 288, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 292, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 293, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 297, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 294, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 296, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 295, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 298, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 299, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 300, wait: 1, signal: 0, busy: 0
Thread Pool : tp_work_thread begin wait id: 211, wait: 1, signal: 0, busy: 0
Thread Pool : the callback return(1/300).
Thread Pool : set free (1/300) after the callback return.
Thread Pool : tp_work_thread begin wait id: 1, wait: 1, signal: 0, busy: 0
Thread Pool : the callback return(2/300).
Thread Pool : set free (2/300) after the callback return.
Thread Pool : tp_work_thread begin wait id: 2, wait: 1, signal: 0, busy: 0
Thread Pool : the callback return(3/300).
Thread Pool : set free (3/300) after the callback return.
Thread Pool : tp_work_thread begin wait id: 3, wait: 1, signal: 0, busy: 0
Thread Pool : the callback return(4/300).
Thread Pool : set free (4/300) after the callback return.
Thread Pool : tp_work_thread begin wait id: 4, wait: 1, signal: 0, busy: 0
Thread Pool : the callback return(5/300).
Thread Pool : set free (5/300) after the callback return.
Thread Pool : tp_work_thread begin wait id: 5, wait: 1, signal: 0, busy: 0
Thread Pool : the callback return(6/300).
Thread Pool : set free (6/300) after the callback return.
Thread Pool : tp_work_thread begin wait id: 6, wait: 1, signal: 0, busy: 0
Thread Pool : the callback return(7/300).
Thread Pool : set free (7/300) after the callback return.
Thread Pool : tp_work_thread begin wait id: 7, wait: 1, signal: 0, busy: 0
Thread Pool : the callback return(8/300).
Thread Pool : set free (8/300) after the callback return.
Thread Pool : tp_work_thread begin wait id: 8, wait: 1, signal: 0, busy: 0
Thread Pool : the callback return(9/300).
Thread Pool : set free (9/300) after the callback return.
Thread Pool : tp_work_thread begin wait id: 9, wait: 1, signal: 0, busy: 0
tp_close: kill manage thread 560737136

工程代码已经上传至GitHub上&#xff1a;https://github.com/fyw4/thread-pool

以上。

参考文档&#xff1a;
1.https://www.jianshu.com/p/210eab345423
2.https://blog.csdn.net/hsuxu/article/details/8985931
3.https://blog.csdn.net/qq_36359022/article/details/78796784
4.https://baike.baidu.com/item/线程池/4745661
5.http://www.cnblogs.com/venow/archive/2012/11/22/2779667.html
6.http://www.cnblogs.com/newth/archive/2012/05/09/2492459.html


推荐阅读
author-avatar
书友75271582
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有