如何在pthread_create()函数中传递矩阵作为参数实现矩阵乘法?
多线程矩阵乘pthread相关问题排查方案
前两种实现方案失败的核心原因
- 仅强转传入结果矩阵
m3的方案:矩阵相乘需要同时读取左矩阵m1、右矩阵m2的元素,仅传入结果矩阵指针的话,线程函数内无法获取另外两个矩阵的有效地址,必然运行失败。另外如果你的int**矩阵是分配在栈上的内存,主线程栈内存回收后线程拿到的就是野指针,也会触发异常。 - 全局变量方案报错:大概率是全局矩阵的内存分配存在越界、分配时机错误的问题,或者多线程计算的任务划分超出了矩阵维度,访问非法内存直接报错。
结构体封装后段错误、无法显示第二个矩阵的排查点
按优先级逐一核对即可定位90%以上的问题:
1 矩阵内存分配错误
这是无法显示第二个矩阵、段错误最常见的诱因:
- 不要用栈内存存储矩阵(比如
int m[100][100]这种写法),栈空间大小有限,大矩阵直接栈溢出,且函数退出后栈内存自动回收,线程访问时为野指针。正确的int**矩阵堆分配方式如下:
// 分配row行col列的int矩阵 int** alloc_matrix(int row, int col) { int** mat = (int**)malloc(sizeof(int*) * row); for (int i = 0; i < row; i++) { mat[i] = (int*)malloc(sizeof(int) * col); } return mat; }
- 检查右矩阵
m2的分配、打印逻辑有没有写反行列维度,比如m2实际是4行5列,你按5行4列分配/打印,就会出现越界乱码、无法正常显示的问题。
2 结构体参数生命周期错误
如果你在创建线程的循环中使用栈上的局部结构体变量传参,100%会出现野指针段错误,错误写法示例:
// 错误写法 for (int i = 0; i < thread_num; i++) { ThreadArgs arg; // 栈局部变量,循环迭代时会被覆盖,循环结束后内存回收 arg.m1 = m1; arg.m2 = m2; // 其他参数赋值 pthread_create(&tid[i], NULL, threadMultiply, &arg); }
正确做法是给每个线程的参数单独分配堆内存,在线程函数内用完后释放:
// 正确写法 for (int i = 0; i < thread_num; i++) { ThreadArgs* arg = (ThreadArgs*)malloc(sizeof(ThreadArgs)); arg->m1 = m1; arg->m2 = m2; arg->m3 = m3; // 赋值维度、当前线程负责的计算行范围等参数 pthread_create(&tid[i], NULL, threadMultiply, arg); } // 线程函数内部逻辑 void* threadMultiply(void* arg) { ThreadArgs* args = (ThreadArgs*)arg; // 你的矩阵计算逻辑 free(args); // 释放参数内存 pthread_exit(NULL); }
3 计算范围越界
检查你给每个线程划分的计算任务是否超出矩阵维度:比如结果矩阵m3是3行5列,你给某个线程分配的计算行范围是0~4,访问m3[4]时就会直接越界触发段错误。
4 类型不匹配
检查结构体中的矩阵成员类型是否为int**,如果错写为int*,指针偏移逻辑错误,也会出现乱码、段错误问题。
内容的提问来源于stack exchange,提问作者MJROCKS
相关产品推荐
相关产品推荐

