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

