You need to enable JavaScript to run this app. C多线程程序pthread_join触发Segmentation fault (core dumped)排查
优惠活动
大模型
产品
解决方案
定价
更多

C多线程程序pthread_join触发Segmentation fault (core dumped)排查

段错误根源排查与修正

核心错误定位

你观察到的“pthread_join处触发段错误”只是问题的暴露位置,根因是前面的pthread_create调用已经传入了非法参数,具体错误点如下:

  • pthread_create(&num,NULL,foo(size),NULL)的传参逻辑完全错误:这里不是传入foo函数作为线程入口,而是在执行pthread_create时直接调用了foo(size),把foo的返回值(无合法返回值的野指针)当作pthread_create要求的函数指针类型的第三个参数传入。pthread_create拿到非法参数后根本没有创建成功的线程,返回的num句柄是无意义的随机值,后续用这个无效句柄调用pthread_join时自然触发段错误。
  • 线程入口函数的签名不符合POSIX标准要求:pthread规范要求线程入口必须是void* 函数名(void* 通用参数)的形式,你写的void *foo(int kb)参数类型完全不匹配,哪怕正确传入函数指针,也会因为参数类型不对导致未定义行为。
  • foo函数缺少合法返回值:作为返回void*类型的函数,foo执行完循环后没有任何return语句,编译时就会触发“隐式返回”的警告,函数退出时返回值寄存器存储的是随机值,属于明确的未定义行为。
  • 你声明的float etime();没有对应实现:如果没有链接对应功能的实现代码,第一次调用etime()时就会跳转到无效内存地址触发崩溃,和pthread本身无关。

修正后的正确代码逻辑

线程参数必须通过pthread_create的第四个void*类型参数传递,不能在创建线程时直接调用入口函数,参考关键修正片段:

// 符合POSIX规范的线程入口签名
void *foo(void *arg)
{
    // 将通用参数转换为实际需要的类型
    int kb = (int)(long)arg;
    printf("Allocating memory\n");
    // 必须增加内存分配失败判断
    buffer = calloc(kb, sizeof(char));
    if (buffer == NULL) {
        perror("calloc failed");
        pthread_exit(NULL);
    }
    printf("Memory allocated\n");
    int i;
    printf("After i\n");
    for(i = 0; i < kb; i++)
    {
        buffer[i] = 'z';
    }
    printf("End of for loop\n");
    // 规范的线程退出方式
    pthread_exit(NULL);
}

void et(int size)  
{
    int thrr;
    pthread_t num;
    etime();
    printf("Inside et \n");
    printf("Before calling create thread \n");
    // 正确传参:传入函数指针本身,将size值作为通用参数传递给线程
    thrr = pthread_create(&num, NULL, foo, (void*)(long)size);
    printf("thrr = %d\n", thrr);
    if(thrr != 0)
    {
        printf("Cannot create thread!\n");
        return;
    }
    printf("Thread created successfully\n");
    // 此时num是pthread_create返回的合法句柄,调用join不会触发非法访问
    pthread_join(num, NULL);
    printf("Time taken = %f\n", etime());
}

额外注意事项

  • 64位系统下直接将int类型强转为void*存在整数截断风险,更严谨的传参方式是将size值存在堆内存中,把内存地址通过arg传入线程,线程处理完成后释放内存,避免栈变量失效、整数截断等问题。
  • 编译多线程程序时需要链接pthread库,即使用gcc 源文件.c -o test -lpthread,否则也会出现函数符号找不到导致的崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.02 19:54:10