You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

线程池无任务时如何正确终止所有线程?现有代码为何挂起?

程序完成所有任务后挂起的原因分析

我设置了全局变量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;
}

核心问题分析

  1. 变量拼写错误
    全局变量定义为taskCompeleted(多了一个字母e),但线程退出判断条件里用的是taskCompleted,两者不是同一个变量。这导致taskCompleted始终为0,永远满足不了>=10的退出条件,线程会一直阻塞在pthread_cond_wait中,程序无法正常退出。

  2. 线程未被唤醒
    即使修复了拼写错误,当所有任务处理完毕后,可能还有线程阻塞在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 19:44:53