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

多线程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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:59:51