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

Ubuntu下使用pthreads实现矩阵向量乘法触发Segmentation fault问题

Ubuntu下多线程矩阵-向量乘法段错误问题修复

问题根源分析

  1. Windows专属代码冗余:代码开头的#pragma comment(lib, "pthreadVC2.lib")是Windows平台链接pthread库的指令,Ubuntu下GCC完全不识别;#define _CRT_SECURE_NO_WARNINGS 1是VS编译器的安全警告禁用宏,Linux下无效,这两行直接删掉即可。
  2. 命令行参数未检查:main函数直接读取argv[1]设置线程数,如果运行时没传参数,argv[1]是空指针,调用atoi会直接触发段错误,表现为程序还没输出任何内容就崩溃,看起来像没进入main函数。
  3. 函数参数类型不匹配:Print_vector函数的第三个参数定义为double m,但实际传入的是int类型的矩阵行数,虽然不会直接崩溃,但属于类型错误,容易引发逻辑问题。
  4. 线程任务划分不完整:当矩阵行数m不能被线程数整除时,现有代码会遗漏最后几行的计算,需要调整线程的行范围逻辑。

修复后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

/* Global variables */
int     thread_count = 8;
int     m, n;
double* A = NULL;
double* x = NULL;
double* y = NULL;

/* Serial functions */
void Usage(char* prog_name);
void Read_matrix(char* prompt, double A[], int m, int n);
void Read_vector(char* prompt, double x[], int n);
void Print_matrix(char* title, double A[], int m, int n);
void Print_vector(char* title, double y[], int m);

/* Parallel function */
void* Pth_mat_vect(void* rank);

/*------------------------------------------------------------------*/
int main(int argc, char* argv[]) {
    long thread;
    pthread_t* thread_handles;

    // 检查命令行参数
    if (argc != 2) {
        fprintf(stderr, "用法: %s <线程数>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    thread_count = atoi(argv[1]);
    thread_handles = malloc(thread_count * sizeof(pthread_t));
    if (thread_handles == NULL) {
        fprintf(stderr, "malloc线程句柄失败\n");
        exit(EXIT_FAILURE);
    }

    printf("Enter m and n\n");
    scanf("%d%d", &m, &n);

    A = malloc(m * n * sizeof(double));
    x = malloc(n * sizeof(double));
    y = malloc(m * sizeof(double));
    // 检查内存分配是否成功
    if (A == NULL || x == NULL || y == NULL) {
        fprintf(stderr, "malloc内存失败\n");
        exit(EXIT_FAILURE);
    }

    Read_matrix("Enter the matrix", A, m, n);
    Print_matrix("We read", A, m, n);

    Read_vector("Enter the vector", x, n);
    Print_vector("We read", x, n);

    for (thread = 0; thread < thread_count; thread++)
        pthread_create(&thread_handles[thread], NULL,
            Pth_mat_vect, (void*)thread);

    for (thread = 0; thread < thread_count; thread++)
        pthread_join(thread_handles[thread], NULL);

    Print_vector("The product is", y, m);

    free(A);
    free(x);
    free(y);
    free(thread_handles); // 释放线程句柄内存

    return 0;
}  /* main */


/*------------------------------------------------------------------
 * Function:    Read_matrix
 * Purpose:     Read in the matrix
 * In args:     prompt, m, n
 * Out arg:     A
 */
void Read_matrix(char* prompt, double A[], int m, int n) {
    int i, j;

    printf("%s\n", prompt);
    for (i = 0; i < m; i++)
        for (j = 0; j < n; j++)
            scanf("%lf", &A[i * n + j]);
}  /* Read_matrix */


/*------------------------------------------------------------------
 * Function:        Read_vector
 * Purpose:         Read in the vector x
 * In arg:          prompt, n
 * Out arg:         x
 */
void Read_vector(char* prompt, double x[], int n) {
    int   i;

    printf("%s\n", prompt);
    for (i = 0; i < n; i++)
        scanf("%lf", &x[i]);
}  /* Read_vector */


/*------------------------------------------------------------------
 * Function:       Pth_mat_vect
 * Purpose:        Multiply an mxn matrix by an nx1 column vector
 * In arg:         rank
 * Global in vars: A, x, m, n, thread_count
 * Global out var: y
 */
void* Pth_mat_vect(void* rank) {
    long my_rank = (long)rank;
    int i, j;
    int local_m = m / thread_count;
    int my_first_row = my_rank * local_m;
    // 处理不能整除的情况,最后一个线程负责剩余所有行
    int my_last_row = (my_rank == thread_count - 1) ? m - 1 : (my_rank + 1) * local_m - 1;

    for (i = my_first_row; i <= my_last_row; i++) {
        y[i] = 0.0;
        for (j = 0; j < n; j++)
            y[i] += A[i * n + j] * x[j];
    }

    return NULL;
}  /* Pth_mat_vect */


/*------------------------------------------------------------------
 * Function:    Print_matrix
 * Purpose:     Print the matrix
 * In args:     title, A, m, n
 */
void Print_matrix(char* title, double A[], int m, int n) {
    int   i, j;

    printf("%s\n", title);
    for (i = 0; i < m; i++) {
        for (j = 0; j < n; j++)
            printf("%4.1f ", A[i * n + j]);
        printf("\n");
    }
}  /* Print_matrix */


/*------------------------------------------------------------------
 * Function:    Print_vector
 * Purpose:     Print a vector
 * In args:     title, y, m
 */
void Print_vector(char* title, double y[], int m) {
    int   i;

    printf("%s\n", title);
    for (i = 0; i < m; i++)
        printf("%4.1f ", y[i]);
    printf("\n");
}  /* Print_vector */

编译与运行步骤

  1. 保存修复后的代码为mat_vec.c
  2. 使用GCC编译,必须链接pthread库:
    gcc -o mat_vec mat_vec.c -lpthread
    
  3. 运行程序,必须传入线程数参数(例如4线程):
    ./mat_vec 4
    
  4. 按照提示输入矩阵行数m、列数n,依次输入矩阵元素和向量元素即可。

内容的提问来源于stack exchange,提问作者Shuhao Chu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 09:15:59