Linux下C语言线程池实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wangqingchuan92/article/details/87072962

0x00前言

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

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

0x01线程池工作原理简介

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

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

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

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

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

0x02 为什么使用线程池

1.减少因频繁创建以及销毁线程产生的系统开销。
大多数网络服务器的特点就是单位时间内处理数量巨大的连接请求。这些请求的处理时间通常比较短(线程创建时间T1,请求处理时间T2,销毁线程时间T3,T2 < T1 + T3),请求次数也比较频繁。为了处理这些请求,服务器系统将处于一个不停的线程创建和销毁的状态,在线程执行时间非常短的情况下,这笔开销不可不计。

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; 	//管理线程的ID
    tp_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;i<this->min_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);	//创建工作线程,见5
        if(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);			//创建管理线程,见4
    if(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;i<this->cur_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;i<this->cur_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) < BUSY_THRESHOLD)//当线程池内只有小部分线程处于工作状态时,线程池将自动销毁一部分的线程,回收系统资源。BUSY_THRESHOLD为0.5
    {

		printf("Thread Pool : get_tp_status(%d/%d) to delete.\n", busy_num, this->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 = 0;
    int i = 0;
    int waitloop = 0;

    pthread_mutex_lock(&this->tp_lock);

    if(this->cur_th_num <= this->min_th_num)				//若当前线程数量小于线程池最小数量,无需销毁线程
    {
        pthread_mutex_unlock(&this->tp_lock);
        printf("Thread Pool : No need to delete thread!\n");
        return FALSE;
    }

    i = this->cur_th_num - 1;
    pthread_mutex_lock(&this->thread_info[i].thread_lock); 	//为线程池中编号最后的、空闲的线程上锁

    if(this->thread_info[i].is_busy)						//若该线程在工作,解锁
    {
        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+1));
        return FALSE;
    }

	//删除该空闲线程操作
    this->thread_info[i].is_busy  = FALSE;
    this->thread_info[i].func = (void (*)(void *))tp_doNothing_forDelete; 	//将当前线程指向tp_work_thread func函数//(void (*)(void *)):函数返回值数据类型 (*指针变量名)(函数的实际参数或者函数参数的类型)
    this->thread_info[i].input = 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+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 != TRUE)							//为该线程等待一段时间
    {
        usleep(10000);
        waitloop++;
        if (waitloop >= 100)
        {
            break;
        }
    }

    ret = pthread_mutex_destroy(&this->thread_info[i].thread_lock);		//销毁当前线程互斥锁
    if (0 != ret)
    {
        printf("Thread Pool : mutex destroy failed (ret %d) on thread %d (waitloop %d).\n", ret, (i+1), waitloop);
    }

    ret = pthread_cond_destroy(&this->thread_info[i].thread_cond); 		//销毁当前线程条件变量
    if (0 != ret)
    {
        printf("Thread Pool : cond destroy failed (ret %d) on thread %d (waitloop %d).\n", ret, (i+1), waitloop);
    }

    //ret = pthread_kill(this->thread_info[this->cur_th_num-1].thread_id, SIGKILL);
    ret = pthread_cancel(this->thread_info[i].thread_id);				//申请销毁线程
    if (0 != ret)
    {
       	printf("Thread Pool : cancel failed (ret %d) on thread %d (waitloop %d).\n", ret, (i+1), waitloop);
    }

    this->cur_th_num--;					//销毁了一个线程,使得当前线程池线程数量减1
    pthread_mutex_unlock(&this->tp_lock);

    printf("Thread Pool : cancel success thread %d, cur num %d (waitloop %d)!\n", (i+1), this->cur_th_num, waitloop);

    return TRUE;
}
//删除操作
void tp_doNothing_forDelete(tp_thread_pool *this)
{
    int waitLoop = 0;

    if (NULL == this)
    {
        printf("Thread Pool : delete thread FAIL because of NULL!\n");
        return;
    }

    this->thread_info[this->cur_th_num-1].is_destroy = TRUE;//查看该线程(编号最后一个线程)是否销毁
    printf("Thread Pool : tp_delete_thread set destory %d TRUE. \n", (this->cur_th_num));

    while (1)
    {
        usleep(10000);
        waitLoop++;
        if (waitLoop >= 1000)
        {
            break;
        }
    }

    this->thread_info[this->cur_th_num-1].is_destroy = FALSE; //查看该线程(编号最后一个线程)是否销毁

    printf("Thread Pool : delete thread %d FAIL because of timeout!\n", (this->cur_th_num));

    return;
}

5.工作线程
工作线程逻辑示意图:
在这里插入图片描述

//工作线程
void *tp_work_thread(void *pthread)
{
    pthread_t curid;
    int nseq;
    tp_thread_pool *this = (tp_thread_pool*)pthread;

    curid = pthread_self(); 						//获得该线程自身ID
    nseq = 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+1, (int)curid);
        pthread_exit(NULL);
    }

    while(TRUE)
    {
        pthread_mutex_lock(&this->thread_info[nseq].thread_lock); 	//在线程池中对编号为nseq线程加锁
        this->thread_info[nseq].is_wait = TRUE;						//设置为真,等待被调用

        do
        {
            printf("Thread Pool : tp_work_thread begin wait id: %d, wait: %d, signal: %d, busy: %d\n",(nseq + 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 + 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) != TRUE);  	//挂起该线程,等待信号

        this->thread_info[nseq].is_busy = TRUE;				  	//被唤醒后,该线程为工作状态
        this->thread_info[nseq].is_wait = FALSE;				//表示不能被调用
        this->thread_info[nseq].is_signal = FALSE;				//没有收到signal_cond信号

        printf("Thread Pool : tp_work_thread got signal (%d/%d) busy %d.\n", (nseq + 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 + 1), this->cur_th_num, this->thread_info[nseq].is_busy);

        (*(this->thread_info[nseq].func))(this->thread_info[nseq].input); //执行用户定义的函数func以及参数input,直至退出

        printf("Thread Pool : the callback return(%d/%d).\n", (nseq + 1), this->cur_th_num);

        pthread_mutex_lock(&this->thread_info[nseq].thread_lock);
        this->thread_info[nseq].is_busy = FALSE; 						   //表示该线程现在处于空闲状态
        pthread_mutex_unlock(&this->thread_info[nseq].thread_lock);

        printf("Thread Pool : set free (%d/%d) after the callback return.\n", (nseq + 1), this->cur_th_num);
    }
}


6.为消息分类处理函数寻找空闲线程
对于tp_process_job()的理解,可以参考下面的逻辑示意图:

在这里插入图片描述

//对外接口
int tp_process_job(tp_thread_pool *this, void(*pFunc)(void*), void *pInput ,void *pOutput)
{
    int i;
    int waitLoop = 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 = 0; i < this->cur_th_num; i++)
	{

        printf("Thread Pool : tp_process_job for(%d/%d).\n", i+1, this->cur_th_num);

        pthread_mutex_lock(&this->thread_info[i].thread_lock); 	//从队列中0开始找,上锁

        printf("Thread Pool : tp_process_job get lock(%d/%d).\n", i+1, this->cur_th_num);

        if(!this->thread_info[i].is_busy)  						//寻找在线程池中空闲线程
		{
            printf("Thread Pool : tp_process_job get free(%d/%d).\n", i+1, this->cur_th_num);

		    this->thread_info[i].is_busy = TRUE;				//找到空闲线程后,设置该线程为忙碌

		    if(this->thread_info[i].is_wait != TRUE)          	//判断该线程是否能够被调用
            {
                printf("Thread Pool : tp_process_job wait fail. id : %d, all num : %d, wait : %d, busy : %d, signal : %d.\n",i+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 = FALSE;			//若该线程不能别调用将该标志位恢复原来的状态
                pthread_mutex_unlock(&this->thread_info[i].thread_lock);
                return 1; 										//失败返回
            }
            else
            {
                this->thread_info[i].is_signal = TRUE;          //设置该线程收到cond_signal信号
                this->thread_info[i].func = pFunc;				//函数指针指向消息分类处理函数
                this->thread_info[i].input = pInput;			//指向消息分类函数输入参数
                this->thread_info[i].output = pOutput;			//指向消息分类函数输出参数

                pthread_cond_signal(&this->thread_info[i].thread_cond);  //唤醒该线程(tp_work_thread)

                this->thread_info[i].is_busy = FALSE;

                printf("Thread Pool : tp_process_job send signal. id : %d, all num : %d, wait : %d, busy : %d, signal : %d.\n",i+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);
    	}
    }


	//若线程池中当前所有线程都忙碌(thread_info[i].is_busy  == TRUE),则在线程池中新加一个线程并使用
    pthread_mutex_lock(&this->tp_lock); //对线程池上锁

    if(this->add_thread(this))			//若添加线程成功
	{
        i = this->cur_th_num - 1;		//cur_th_num在add_thread已经加1,为了显示正确的线程队列位置i,减1

        printf("Thread Pool : add new one. id : %d, all num : %d.\n", i+1, this->cur_th_num);

        pthread_mutex_unlock(&this->tp_lock);

        waitLoop = 0;
        while (this->thread_info[i].is_wait != TRUE)		//判断该线程是否能够被调用
        {
            usleep(1000);									//等待
            waitLoop++;
            if (waitLoop >= 10)
            {
                break;
            }
        }

        pthread_mutex_lock(&this->thread_info[i].thread_lock);

        if (waitLoop >= 10)									//若规定的时间结束仍不能被调用
        {
            this->thread_info[i].is_busy = 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+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 = TRUE;
            this->thread_info[i].is_busy = FALSE;
            this->thread_info[i].func = pFunc;
            this->thread_info[i].input = pInput;
    	    this->thread_info[i].output = 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+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 <= this->cur_th_num)	//若新建了一个线程之后,当前线程数超过线程池最大线程数则返回0
    {
        printf("Thread Pool : The thread poor is full(%d/%d).\n", this->cur_th_num, this->max_th_num);
        return FALSE;
    }

    new_thread = &this->thread_info[this->cur_th_num]; //将新建线程插入到线程池队列

	//互斥锁和条件变量等初始化
    err = pthread_cond_init(&new_thread->thread_cond, NULL);
    if (0 != err)
    {
        printf("Thread Pool : add cond_init ret %d, all: %d\n", err, this->cur_th_num);
        return FALSE;
    }

    err = pthread_mutex_init(&new_thread->thread_lock, NULL);
    if (0 != err)
    {
        printf("Thread Pool : add mutex_init ret %d, all: %d\n", err, this->cur_th_num);
        return FALSE;
    }

    new_thread->is_signal = FALSE;
    new_thread->is_wait = FALSE;
    new_thread->is_destroy = FALSE;
    new_thread->is_busy = TRUE;

    this->cur_th_num = this->cur_th_num + 1; //将当前线程数量加1

    err = pthread_create(&new_thread->thread_id, NULL, tp_work_thread, this); //创建新工作线程tp_work_thread
    if(0 != err) //若失败,将当前线程数量减1恢复原数量
    {
        printf("Thread Pool : create new thread failed.\n");
        this->cur_th_num = this->cur_th_num - 1;
        return FALSE;
    }

    return TRUE;
}

0x04运行结果

代码完成后,编写一个程序运行脚本make.sh,方便编译:

gcc -o ThreadTest *.c -lpthread 

整个工程目录:
在这里插入图片描述

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

fip@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上:https://github.com/fyw4/thread-pool

以上。

参考文档:
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

猜你喜欢

转载自blog.csdn.net/wangqingchuan92/article/details/87072962