多线程C矩阵乘法程序故障求助:主线程永久阻塞
矩阵乘法多线程程序永久阻塞问题排查与修复
咱们一步步拆解你的代码里的问题,先解决导致主线程永久阻塞的核心原因,再处理其他潜在问题:
核心问题:pthread_create参数顺序完全错误
这是程序黑屏、主线程永久阻塞的根本原因。pthread_create的标准调用原型是:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
但你的代码里写成了:
pthread_create(count,&thread_array[count],&attr,runner,data);
这里完全搞反了参数顺序:第一个参数应该是指向线程ID变量的指针(也就是&thread_array[count]),但你传了一个整数count;后续的参数位置也全部错位,导致线程根本创建失败。而主线程后续调用pthread_join等待这些未成功创建的线程,自然会永久阻塞。
正确的pthread_create调用应该是:
pthread_create(&thread_array[count], &attr, runner, data);
其他需要修正的潜在问题
除了核心阻塞问题,代码里还有几个需要修复的点:
- 错误的内存释放:
thread_array是在栈上声明的数组(pthread_t thread_array[M*N];),栈内存不需要也不能用free释放,这会触发未定义行为,必须删除free(thread_array);这一行。 - 未初始化随机数生成器:
rand()调用前没有用srand(time(NULL))初始化,每次运行生成的矩阵元素都是完全相同的,建议在main函数开头添加这行代码。 - 无用的
idl数组:代码里声明了idl数组但从未使用,直接删除即可,让代码更简洁。 - 线程内存泄漏:在创建线程时用
malloc分配了struct v的内存,但在线程函数里没有释放,需要在runner函数退出前调用free(data)清理内存。 - fill_matrix函数的兼容性问题:当前函数参数只适配列数为
N的矩阵,后续如果修改M/K/N的值可能出问题,建议改成通用的内存访问方式(见下面修正后的代码)。
修正后的完整代码
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #define size 10 #define M size #define K size #define N size int A[M][K]; int B[K][N]; int C[M][N]; struct v { int i; /* 行号 */ int j; /* 列号 */ }; void *runner(void *param); /* 线程函数 */ // 通用的矩阵填充函数,适配任意行列数 void fill_matrix(int rows, int cols, int *matrix) { for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { *(matrix + i*cols + j) = rand() % 100 + 1; } } } int main(int argc, char *argv[]) { int i, j, count = 0; srand(time(NULL)); // 初始化随机数生成器 fill_matrix(M, K, (int*)A); fill_matrix(K, N, (int*)B); clock_t start = clock(); pthread_t thread_array[M*N]; pthread_attr_t attr; pthread_attr_init(&attr); for(i = 0; i < M; i++) { for(j = 0; j < N; j++) { struct v *data = (struct v *) malloc(sizeof(struct v)); data->i = i; data->j = j; // 修正后的pthread_create调用 pthread_create(&thread_array[count], &attr, runner, data); count++; } } // 等待所有线程完成 for(int k = 0; k < M*N; k++){ pthread_join(thread_array[k], NULL); } clock_t end = clock(); printf("执行时间:%f 秒\n", (float)(end-start)/CLOCKS_PER_SEC ); // 可选:打印结果矩阵验证正确性 // printf("结果矩阵C:\n"); // for(int x=0;x<M;x++){ // for(int y=0;y<N;y++){ // printf("%d ", C[x][y]); // } // printf("\n"); // } return 0; } void *runner(void *param) { struct v *data = param; int n, sum = 0; for(n = 0; n < K; n++){ sum += A[data->i][n] * B[n][data->j]; } C[data->i][data->j] = sum; free(data); // 释放线程参数的内存,避免泄漏 pthread_exit(NULL); }
内容的提问来源于stack exchange,提问作者bedrockelectro
相关产品推荐
相关产品推荐

