线程池无任务时如何正确终止所有线程?现有代码为何挂起?
程序完成所有任务后挂起的原因分析
我设置了全局变量taskCompleted来跟踪已完成任务的数量;当该变量达到特定数值时,线程会终止。但程序在完成所有提交的任务后似乎仍然挂起,这是为什么?
原代码
#define THREAD_NUM 4 typedef struct Task { int a, b; } Task; Task taskQueue[256]; int taskCount = 0; int taskCompeleted = 0; pthread_mutex_t mutex; pthread_cond_t taskAvailable; void executeTask(Task* task) { //usleep(50000); int result = task->a + task->b; printf("The sum of %d and %d is %d\n", task->a, task->b, result); } void submitTask(Task task) { pthread_mutex_lock(&mutex); taskQueue[taskCount] = task; taskCount++; pthread_cond_signal(&taskAvailable); pthread_mutex_unlock(&mutex); } void* startThread(void* args) { while (1) { Task task; pthread_mutex_lock(&mutex); while (taskCount == 0) { if (taskCompleted >= 10) { pthread_mutex_unlock(&mutex); return 0; } pthread_cond_wait(&taskAvailable, &mutex); } task = taskQueue[0]; int i; for (i = 0; i < taskCount - 1; i++) { taskQueue[i] = taskQueue[i + 1]; } taskCount--; taskCompeleted++; pthread_mutex_unlock(&mutex); executeTask(&task); } } int main(int argc, char* argv[]) { pthread_t th[THREAD_NUM]; pthread_mutex_init(&mutex, NULL); pthread_cond_init(&taskAvailable, NULL); int i; for (i = 0; i < THREAD_NUM; i++) { if (pthread_create(&th[i], NULL, &startThread, NULL) != 0) { perror("Failed to create the thread"); } } for (i = 0; i < 10; i++) { Task t = { .a = i, .b = i }; submitTask(t); } for (int i = 0; i < THREAD_NUM; i++) { if (pthread_join(th[i], NULL) != 0) { perror("Failed to join the thread"); } } pthread_mutex_destroy(&mutex); pthread_cond_destroy(&taskAvailable); return 0; }
核心问题分析
变量拼写错误
全局变量定义为taskCompeleted(多了一个字母e),但线程退出判断条件里用的是taskCompleted,两者不是同一个变量。这导致taskCompleted始终为0,永远满足不了>=10的退出条件,线程会一直阻塞在pthread_cond_wait中,程序无法正常退出。线程未被唤醒
即使修复了拼写错误,当所有任务处理完毕后,可能还有线程阻塞在pthread_cond_wait上。此时没有新的任务提交触发pthread_cond_signal,这些线程永远不会醒来检查退出条件,导致pthread_join一直等待线程终止,程序挂起。
修复方案
- 修正变量拼写,将全局变量和判断条件统一为
taskCompleted; - 在所有任务提交完成后,发送条件变量广播,唤醒所有等待的线程,让它们有机会检查退出条件。
修复后的关键代码片段
// 修正全局变量拼写 int taskCompleted = 0; // 线程函数中修正判断逻辑 while (taskCount == 0) { if (taskCompleted >= 10) { pthread_mutex_unlock(&mutex); return 0; } pthread_cond_wait(&taskAvailable, &mutex); } // main函数中提交完所有任务后添加广播 for (i = 0; i < 10; i++) { Task t = { .a = i, .b = i }; submitTask(t); } // 唤醒所有等待的线程 pthread_mutex_lock(&mutex); pthread_cond_broadcast(&taskAvailable); pthread_mutex_unlock(&mutex);
内容的提问来源于stack exchange,提问作者ElleryL
相关产品推荐
相关产品推荐

