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

valgrind检测含pthread_create的程序为何有时报疑似内存泄漏?

问题分析与解决

代码示例

#include <pthread.h>
#include <stdio.h>

void* handle_client(void* arg);

int main(int argc, char *argv[])
{
    pthread_t pthr_handle;
    pthread_create(&pthr_handle, NULL, &handle_client, NULL);
    pthread_detach(pthr_handle);
    pthread_exit(NULL);
    return 0;
}

void* handle_client(void* arg)
{
    printf("Hello from thread!\n");
    pthread_exit(NULL);
    return NULL;
}

问题描述

使用valgrind检测该程序时,偶发出现以下提示:

possibly lost: 272 bytes in 1 blocks

有时检测则显示无泄漏。推测该提示与主线程退出后子线程仍在运行有关,同时疑惑pthread_exit是否需要等待其他线程退出,希望消除valgrind的这类疑似泄漏提示。

核心原因

  1. pthread_exit的行为:主线程调用pthread_exit后,主线程自身退出,但进程不会立即终止——进程会等待所有非分离状态的线程结束后才终止。但你的子线程被设置为分离状态(pthread_detach),分离线程的资源会在自身结束时自动回收,不需要其他线程join。
  2. 偶发误报的原因:主线程退出后,子线程可能仍在执行,valgrind的检测时机若恰好落在子线程资源未完全释放的阶段,就会触发疑似泄漏提示;若子线程在valgrind检测前已完成并清理资源,就不会出现提示。

解决方法

方法1:取消线程分离,改用pthread_join等待子线程结束

这是最稳妥的方式,确保主线程等待子线程执行完毕、资源完全回收后再退出,从根源避免valgrind误报。修改后的代码:

#include <pthread.h>
#include <stdio.h>

void* handle_client(void* arg);

int main(int argc, char *argv[])
{
    pthread_t pthr_handle;
    pthread_create(&pthr_handle, NULL, &handle_client, NULL);
    // 等待子线程执行完成,自动回收其资源
    pthread_join(pthr_handle, NULL);
    pthread_exit(NULL);
    return 0;
}

void* handle_client(void* arg)
{
    printf("Hello from thread!\n");
    pthread_exit(NULL);
    return NULL;
}

方法2:保留线程分离,用同步机制让主线程等待子线程完成

如果必须使用分离线程,可通过互斥锁+条件变量的同步方式,让子线程完成后通知主线程,主线程再退出:

#include <pthread.h>
#include <stdio.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int thread_finished = 0;

void* handle_client(void* arg);

int main(int argc, char *argv[])
{
    pthread_t pthr_handle;
    pthread_create(&pthr_handle, NULL, &handle_client, NULL);
    pthread_detach(pthr_handle);

    // 等待子线程完成信号
    pthread_mutex_lock(&mutex);
    while (!thread_finished) {
        pthread_cond_wait(&cond, &mutex);
    }
    pthread_mutex_unlock(&mutex);

    pthread_exit(NULL);
    return 0;
}

void* handle_client(void* arg)
{
    printf("Hello from thread!\n");

    // 通知主线程任务完成
    pthread_mutex_lock(&mutex);
    thread_finished = 1;
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);

    pthread_exit(NULL);
    return NULL;
}

方法3:使用valgrind抑制规则(不推荐)

如果不想修改代码,可通过valgrind的抑制文件屏蔽这类误报,但这只是掩盖问题,而非从根源解决。你可以生成抑制文件并在检测时加载:

# 生成抑制文件
valgrind --gen-suppressions=all ./your_program > suppressions.txt
# 使用抑制文件检测
valgrind --suppressions=suppressions.txt ./your_program

补充说明

pthread_exit本身不需要主动等待分离线程,但主线程提前退出会导致valgrind的检测窗口与子线程的资源回收窗口重叠,从而产生误报。让主线程等待所有线程完成后再退出,是消除这类提示的最佳实践。

内容的提问来源于stack exchange,提问作者Vitor Mouro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 18:50:23