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

C线程池线程执行后未返回destroy_threadpool,程序无法终止(附Valgrind错误)

问题分析与解决方法

1. 线程池销毁阻塞(线程无法返回destroy_threadpool)

这种情况基本是工作线程未正确响应终止信号,卡在任务等待逻辑里:

  • 检查工作线程的主循环条件:必须同时判断线程池关闭标志和任务队列是否为空。错误示例:
    while (!threadpool->shutdown) { // 仅判断关闭标志,队列空时会一直阻塞等待
        // 等待任务逻辑
    }
    
    正确写法:
    while (!threadpool->shutdown || !task_queue_is_empty(threadpool->queue)) {
        pthread_mutex_lock(&threadpool->mutex);
        pthread_cond_wait(&threadpool->cond, &threadpool->mutex);
        // 处理任务
        pthread_mutex_unlock(&threadpool->mutex);
    }
    
  • 确认destroy_threadpool中是否用pthread_cond_broadcast唤醒所有阻塞线程:用broadcast而非signal,确保所有等待的工作线程都能收到终止信号。
  • 排查任务处理逻辑:如果线程在处理单个任务时进入无限循环(比如未正确处理连接关闭),会导致线程无法退出循环响应终止指令。

2. filter_address_from_string的大小为1的无效读取

这类越界读取几乎都是字符串边界处理错误:

  • 检查循环遍历条件:如果用for (int i = 0; i <= strlen(s); i++),当i等于字符串长度时,s[i]是'\0',继续i++会访问超出字符串末尾1字节的内存,改成i < strlen(s)即可。
  • 确认输入字符串是否以'\0'终止:如果字符串从网络/文件读取时未手动添加终止符,strlen会读取到内存随机位置,导致后续操作越界,读取后要在缓冲区末尾补上'\0'。
  • 检查字符串工具函数的使用:比如strncpy要给目标缓冲区留足'\0'的位置;使用strtok后不要访问原字符串的已分割部分,避免野指针。

3. read_file_content的74字节内存泄漏

泄漏原因就是分配的内存未被释放,分两类排查:

  • 检查调用代码:如果函数返回malloc分配的内存,调用者必须在使用完成后调用free。示例:
    char* content = read_file_content("proxy.conf");
    // 使用content处理逻辑
    free(content); // 必须添加该行释放内存
    
  • 检查函数内部错误分支:如果函数中途出错(如文件打开失败、读取失败),要先释放已分配的内存再返回。错误示例:
    char* buf = malloc(1024);
    if ((fp = fopen(path, "r")) == NULL) {
        return NULL; // 未释放buf导致泄漏
    }
    
    正确写法:
    char* buf = malloc(1024);
    if ((fp = fopen(path, "r")) == NULL) {
        free(buf);
        return NULL;
    }
    

内容的提问来源于stack exchange,提问作者EladO O

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 07:27:16