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

pthread_create()调用触发Segmentation Fault问题求助

问题分析与修复方案

你的代码触发段错误(SIGSEGV)有两个核心原因,下面逐一拆解并给出修复方案:

1. 线程函数签名不匹配 + pthread_create参数错误

pthread_create要求的线程函数签名必须是void* (*)(void*),但你定义的sleeping是void* sleeping(int),类型完全不兼容。更致命的是,你调用pthread_create时写了sleeping(i)——这不是传递函数指针,而是直接在主线程里执行了sleeping函数,把它的返回值(函数未写return,返回值未定义)当成函数指针传给pthread_create,必然导致后续调用非法地址,触发段错误。

2. 线程函数缺少合法返回值

sleeping函数声明返回void*,但函数末尾没有return语句,这会触发未定义行为,可能破坏栈结构,进一步加剧崩溃风险。

修复后的完整代码

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

#define NUM_THREADS 5

// 修正线程函数签名,完全符合pthread要求
void *sleeping(void *arg);  

int main (int argc, char *argv[]){
    int i, status;
    pthread_t tid[NUM_THREADS];    

    // 为每个线程分配独立的参数空间,避免线程间竞争同一变量
    for (i = 0; i < NUM_THREADS; i++){
        int *thread_num = malloc(sizeof(int));
        if (thread_num == NULL) {
            perror("Could not allocate memory for thread num");
            exit(EXIT_FAILURE);
        }
        *thread_num = i;

        // 第三个参数传函数指针,第四个参数传线程序号的指针
        status = pthread_create(&tid[i], NULL, sleeping, (void *)thread_num);
        if (status != 0){
            printf("Error pthread_create(), error code %i\n", status);
            exit(EXIT_FAILURE);
        }
    }

    for (i = 0; i < NUM_THREADS; i++) {
        status = pthread_join(tid[i], NULL);
        if (status != 0){
            printf("Error pthread_join(), error code %i\n", status);
            exit(EXIT_FAILURE);
        }
    }

    printf ("main() reporting that all %d threads have terminated\n", NUM_THREADS);
    return 0;
} 

void *sleeping(void *arg){
    int thread_id = *(int*)arg;
    // 释放主线程分配的内存,避免泄漏
    free(arg);

    printf ("thread %d belongs to process %d \n",
            thread_id, (int)getpid());
    printf ("thread %d sleeping %d seconds ...\n",
            thread_id, thread_id);
    
    sleep(thread_id);
    printf ("\nthread %d awakening\n", thread_id);

    // 返回合法的void*类型值
    return NULL;
}

额外说明

  • 每个线程的序号通过独立malloc的内存传递,避免了直接传&i导致的线程读取到被主线程修改后的错误值的问题。
  • 线程函数内必须释放主线程分配的内存,否则会产生内存泄漏。
  • 原代码中未实际使用的SLEEP_TIME宏已移除。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:55:18