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

使用pthread_create传递struct参数时的内存泄漏问题排查

内存泄漏排查分析

核心泄漏原因

你的代码中parameters结构体的内存存在泄漏风险,关键问题在于:

  • 主线程创建子线程后,若// some heavy main logic执行耗时极短,会快速进入pthread_cancel流程
  • 子线程刚启动时,可能还没执行到threadFunc里的free(params)就被异步取消,导致这块通过malloc分配的内存永远无法释放

修复方案

方案1:确保参数内存先被释放

调整线程函数内的执行顺序,先设置延迟取消保证参数能安全释放,之后再切换为异步取消:

void *threadFunc(parameters *params)
{
    // 先设置延迟取消,避免线程在释放参数前被终止
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
    // 此时线程不会被异步中断,可安全释放参数内存
    free(params);
    // 按需切换为异步取消
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
    while (1)
    {
        // do magic
    }
}

方案2:主线程统一管理参数内存

如果子线程的取消时机无法预测,可由主线程负责参数内存的释放,需要先保存所有参数指针:

int main(int argc, char *argv[])
{
    pthread_t *tid = malloc(sizeof(pthread_t) * num);
    // 新增数组存储每个线程的参数指针
    parameters **params_arr = malloc(sizeof(parameters*) * num);
    
    for (int i = 0; i < num; i++)
    {
        parameters *p = malloc(sizeof(parameters));
        p->something = i;
        params_arr[i] = p; // 保存参数指针
        
        pthread_create(&tid[i], NULL, (void *)threadFunc, p);
    }
    // some heavy main logic
    for (int i = 0; i < num; i++)
    {
        pthread_cancel(tid[i]);
        pthread_join(tid[i], NULL);
        free(params_arr[i]); // 主线程统一释放参数内存
    }
    free(tid);
    free(params_arr); // 释放存储指针的数组
    // End stuff
}
    
void *threadFunc(parameters *params)
{
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
    while (1)
    {
        // do magic
    }
}

额外提示

  • 异步取消(PTHREAD_CANCEL_ASYNCHRONOUS)会让线程在任意指令点被终止,极易引发资源泄漏、数据不一致问题,非必要优先使用延迟取消(PTHREAD_CANCEL_DEFERRED)
  • 调用pthread_cancel后,必须通过pthread_join等待线程完全终止,避免残留未清理的线程资源

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 16:32:39