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
相关产品推荐
相关产品推荐

