|
这段时间在看线程池的一些东西,在网上搜索到一个程序是创建可动态调整线程数目的线程池实现。
其中有两个函数:
/*真正的线程处理函数,阻塞在cond上 */
static void *tp_work_thread(void *pthread)
/*外部处理函数接口,使线程处理函数对外部透明 */
void tp_process_job(tp_thread_pool *this, tp_work *worker, tp_work_desc *job)
线程处理函数tp_work_thread会调用tp_process_job
我的问题是,线程处理函数tp_work_thread是阻塞在调用tp_process_job之前的条件变量上的,当条件不满足时应该是不会调用tp_process_job的吧,那么这个线程处理函数是通过什么唤醒的;另外,tp_process_job有唤醒条件变量的函数,难道用tp_process_job的唤醒函数能够唤醒tp_work_thread的吗?
这两个函数之间的逻辑关系到底是怎样的,我很糊涂,请大家帮忙指点一下,谢谢。
两个函数的源代码分别为:
/**
* member function reality. main interface opened.
* after getting own worker and job, user may use the function to process the task.
* para:
* this: thread pool struct instance ponter
* worker: user task reality.
* job: user task para
* return:
*/
void tp_process_job(tp_thread_pool *this, tp_work *worker, tp_work_desc *job){
int i;
int tmpid;
//fill this->thread_info's relative work key
for(i=0;i<this->cur_th_num;i++){
pthread_mutex_lock(&this->thread_info.thread_lock);
if(!this->thread_info.is_busy){
printf("tp_process_job: %d thread idle, thread id is %d\n", i, this->thread_info.thread_id);
//thread state be set busy before work
this->thread_info.is_busy = TRUE;
pthread_mutex_unlock(&this->thread_info.thread_lock);
this->thread_info.th_work = worker;
this->thread_info.th_job = job;
printf("tp_process_job: informing idle working thread %d, thread id is %d\n", i, this->thread_info.thread_id);
pthread_cond_signal(&this->thread_info.thread_cond);
return;
}
else
pthread_mutex_unlock(&this->thread_info.thread_lock);
}//end of for
//if all current thread are busy, new thread is created here
pthread_mutex_lock(&this->tp_lock);
if( this->add_thread(this) ){
i = this->cur_th_num - 1;
tmpid = this->thread_info.thread_id;
this->thread_info.th_work = worker;
this->thread_info.th_job = job;
}
pthread_mutex_unlock(&this->tp_lock);
//send cond to work thread
printf("tp_process_job: informing idle working thread %d, thread id is %d\n", i, this->thread_info.thread_id);
pthread_cond_signal(&this->thread_info.thread_cond);
return;
}
/**
* internal interface. real work thread.
* para:
* pthread: thread pool struct ponter
* return:
*/
static void *tp_work_thread(void *pthread){
pthread_t curid;//current thread id
int nseq;//current thread seq in the this->thread_info array
tp_thread_pool *this = (tp_thread_pool*)pthread;//main thread pool struct instance
//get current thread id
curid = pthread_self();
//get current thread's seq in the thread info struct array.
nseq = this->get_thread_by_id(this, curid);
if(nseq < 0)
return;
printf("entering working thread %d, thread id is %d\n", nseq, curid);
//wait cond for processing real job.
while( TRUE ){
pthread_mutex_lock(&this->thread_info[nseq].thread_lock);
pthread_cond_wait(&this->thread_info[nseq].thread_cond, &this->thread_info[nseq].thread_lock);
pthread_mutex_unlock(&this->thread_info[nseq].thread_lock);
printf("%d thread do work!\n", pthread_self());
tp_work *work = this->thread_info[nseq].th_work;
tp_work_desc *job = this->thread_info[nseq].th_job;
//process
work->process_job(work, job);
//thread state be set idle after work
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("%d do work over\n", pthread_self());
}
} |
|