C语言线程池异常:任务数量较少时worker函数无法被调用
问题分析与解决
你的线程池在任务数量较少时任务不执行的核心原因是tpool_wait函数的等待逻辑错误:主线程判断是否等待的条件只检查了正在处理任务的线程数(working_cnt),却忽略了任务队列是否还有未处理的任务。
当任务数量少的时候,可能所有任务都已加入队列,但线程还未完成启动或还未开始处理任务,此时working_cnt为0,主线程会错误地认为所有任务都已处理完成,直接退出tpool_wait,随后执行free(vals)释放任务参数内存,并调用tpool_destroy终止线程池。等线程真正启动后,要么任务队列已被销毁,要么线程检测到stop标志直接退出,导致任务永远不会被执行。而任务数量多的时候,部分线程会快速开始处理任务(working_cnt>0),tpool_wait会正确等待直到所有任务完成,所以程序表现正常。
修正方案
修改tpool_wait函数中的等待条件,在非停止状态下,只要任务队列不为空或者有线程正在处理任务,就继续等待:
void tpool_wait(tpool_t *tm) { if (tm == NULL) return; pthread_mutex_lock(&(tm->work_mutex)); while (1) { // 非停止状态:只要有任务未处理或有线程在工作,就等待 // 停止状态:等待所有线程退出 if ((!tm->stop && (tm->working_cnt != 0 || tm->work_first != NULL)) || (tm->stop && tm->thread_cnt != 0)) { pthread_cond_wait(&(tm->working_cond), &(tm->work_mutex)); } else { break; } } pthread_mutex_unlock(&(tm->work_mutex)); }
额外说明
你之前推测的“线程未创建完成就加入任务”不是根本问题——pthread_create返回后,线程会尽快启动并进入等待任务的状态,而tpool_add_work会通过pthread_cond_broadcast唤醒等待的线程,即使线程还未启动,后续启动的线程也会检查任务队列,不会错过任务。真正的问题出在主线程提前结束等待并销毁线程池的逻辑上。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

