使用PTHREADS时出现Segmentation fault (core dumped)问题求助
解决你的Segmentation Fault和线程程序问题
首先,触发你段错误的直接原因是main函数里的一个低级失误:你在调用pthread_create和pthread_join时用了tid[id],但id变量根本没初始化!它是一个未定义的垃圾值,会导致你访问tid数组的越界内存,直接触发段错误。
第一步:紧急修复线程创建/回收的数组索引问题
把main里的循环改成用i作为索引,而不是未初始化的id:
// 创建线程 for(i=0;i<p;i++){ pthread_create(&tid[i],NULL,add,(void *)(long) i); } // 等待线程结束 for(i=0;i<p;i++){ pthread_join(tid[i],NULL); }
改完这部分,你的段错误应该会立即消失。
第二步:修复内存分配的检查逻辑
你现在的内存分配检查是在所有二维数组的行分配完之后才做的,但如果中间某一行malloc失败了,A[i]会是NULL,但你后续的循环还会继续,而且最后只检查了A、B、C的一级指针,没检查二级指针。应该在每次malloc之后都做检查,还要记得清理已分配的内存再退出:
// 分配一级指针 A = (long int**) malloc(N*sizeof(long int*)); B = (long int**) malloc(N*sizeof(long int*)); C = (long int**) malloc(N*sizeof(long int*)); if((A==NULL) || (B == NULL) || (C == NULL)){ printf("Could Not Allocate Memory For Array Pointers\n"); free(tid); exit(1); } // 分配二级指针并检查 for(i=0;i<N;i++){ A[i] = (long int*) malloc(N*sizeof(long int)); B[i] = (long int*) malloc(N*sizeof(long int)); C[i] = (long int*) malloc(N*sizeof(long int)); if((A[i]==NULL) || (B[i] == NULL) || (C[i] == NULL)){ printf("Could Not Allocate Memory For Array Rows\n"); // 清理已分配的内存避免泄漏 for(j=0;j<i;j++){ free(A[j]); free(B[j]); free(C[j]); } free(A); free(B); free(C); free(tid); exit(1); } }
第三步:修复屏障(pthread_barrier)的使用问题
你初始化屏障时用了pthread_barrier_init(&bar,NULL,p);,也就是要求p个线程调用pthread_barrier_wait才能继续,但你的main线程没有参与等待,所以所有工作线程都会卡在pthread_barrier_wait(&bar);这里,程序永远不会结束。
如果你的屏障是用来让所有线程完成计算后再继续,要么:
- 把屏障的count设为
p+1,然后main线程也调用一次pthread_barrier_wait(&bar);(在所有pthread_join之前); - 或者直接去掉这个屏障——因为你已经用
pthread_join等待所有线程结束了,屏障在这里是多余的。
第四步:其他细节优化
Total_Sum要初始化,不然初始值是垃圾值,最终结果会不对:在main里加Total_Sum = 0;- 处理
N不能被p整除的情况,最后一个线程多处理剩下的行,避免计算遗漏:
// 在add函数里修改end的计算 if(id == p-1){ end = N; }
- 程序退出前记得销毁互斥锁和屏障,释放
tid的内存,避免资源泄漏。
修复后的完整代码(关键修改已标注)
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> long int p,N,Total_Sum; long int **A,**B,**C; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_barrier_t bar; void * add(void *arg){ long int i,j,Local_Sum=0; long int lines,start,end,id; id = (long int)arg; lines = N/p; start = id*lines; end = start+lines; // 处理N不能被p整除的情况 if(id == p-1){ end = N; } for(i=start;i<end;i++){ for(j=0;j<N;j++){ A[i][j] = 1; B[i][j] = 1; } } for(i=start;i<end;i++){ for(j=0;j<N;j++){ C[i][j] = A[i][j] * B[i][j]; Local_Sum += C[i][j]; printf("C[%ld][%ld] = %ld\n",i,j,C[i][j]); } } pthread_mutex_lock(&mutex); Total_Sum += Local_Sum; pthread_mutex_unlock(&mutex); // 若保留屏障,需确保main线程也调用wait,否则注释此行 // pthread_barrier_wait(&bar); pthread_exit(0); } int main(int argc, char *argv[]){ long int i,j; pthread_t *tid; if(argc!=3){ printf("Provide Number Of Threads And Size\n"); exit(1); } p = atoi(argv[1]); tid = (pthread_t *) malloc(p*sizeof(pthread_t)); if(tid == NULL){ printf("Could Not Allocate Memory\n"); exit(1); } // 若保留屏障,count设为p+1 // pthread_barrier_init(&bar,NULL,p+1); N = atoi(argv[2]); Total_Sum = 0; // 初始化总和 A = (long int**) malloc(N*sizeof(long int*)); B = (long int**) malloc(N*sizeof(long int*)); C = (long int**) malloc(N*sizeof(long int*)); if((A==NULL) || (B == NULL) || (C == NULL)){ printf("Could Not Allocate Memory For Array Pointers\n"); free(tid); exit(1); } for(i=0;i<N;i++){ A[i] = (long int*) malloc(N*sizeof(long int)); B[i] = (long int*) malloc(N*sizeof(long int)); C[i] = (long int*) malloc(N*sizeof(long int)); if((A[i]==NULL) || (B[i] == NULL) || (C[i] == NULL)){ printf("Could Not Allocate Memory For Array Rows\n"); // 清理已分配内存 for(j=0;j<i;j++){ free(A[j]); free(B[j]); free(C[j]); } free(A); free(B); free(C); free(tid); exit(1); } } for(i=0;i<p;i++){ pthread_create(&tid[i],NULL,add,(void *)(long) i); } // 若保留屏障,main线程在此处wait // pthread_barrier_wait(&bar); for(i=0;i<p;i++){ pthread_join(tid[i],NULL); } // 清理所有资源 for(i=0;i<N;i++){ free(A[i]); free(B[i]); free(C[i]); } free(A); free(B); free(C); free(tid); pthread_mutex_destroy(&mutex); pthread_barrier_destroy(&bar); printf("Final Result Is Equal To: %ld\n",Total_Sum); return 0; }
内容的提问来源于stack exchange,提问作者george nik
相关产品推荐
相关产品推荐

