Skip to main content
 首页 » 编程设计

c之C 中多线程矩阵乘法

2024年02月13日15bhlsheji

我想创建一个 C 程序,使用线程计算两个 N*N 矩阵的乘法。
我通过引用Matrix Multiplication using multiple threads开始这段代码但我不想为结果矩阵的每个单元创建 N * N 线程,而是想创建 N 个线程来同时执行乘法,其中结果矩阵的每一行将由不同的线程计算。

到目前为止,我的代码如下所示:

#include <stdio.h> 
#include <pthread.h> 
#include <stdlib.h> 
#include <string.h> 
 
#define N 2 
 
struct v { 
    int i;  //Row 
    int j;  //Column 
}; 
 
int A[N][N] = {{ 1, 2 }, { 3, 4 }};//Matrix 1 
int B[N][N] = {{ 2, 3 }, { 4, 5 }};//Matrix 2 
int C[N][N];  //Resulting Matrix 
 
static void *fnc(void *arg) { 
    struct v *data = (struct v *)arg; 
    int l; 
    for (l = 0; l < N; l++) { 
        int i = ((struct v *)data[l]).i;  //Row No 
        int j = ((struct v *)data[l]).j;  //Column No 
        int accumulator = 0; 
        int d, sum = 0; 
        for (d = 0; d < N; d++) { 
            sum = sum + A[i][d] * B[d][j]; 
        } 
        C[i][j] = sum; 
        sum = 0; 
    } 
    return; 
} 
 
int main() { 
    pthread_t threads[N]; 
    int i, k; 
    for (i = 0; i < N; i++) { 
        struct v *data[N]; 
        for (k = 0; k < N; k++) { 
            data[k] = (struct v *)malloc(sizeof(struct v)); 
            data[k].i = i; //assign the row of C for thread to calculate 
            data[k].j = k; //assign the column of C for thread to calculate 
        } 
        //In this example it creates 2 threads with passing data. 
        //Data consists of row and column pairs for each thread, that will be calcuting the pairs. 
        //Consider first iteration of this loop: 
        //Thread 1 is created and data consists of (0,0) and (0,1) which are the targeted calculation cells for thread 1.  
        //In the second iteration: Thread 2 will have (1,0) and (1,1) pairs in its data. 
 
        pthread_create(&threads[i], NULL, fnc, data); 
    } 
    for (i = 0; i < N; i++) 
        pthread_join(threads[i], NULL); 
 
   for (i = 0; i < N; i++) 
      for (k = 0; k < N; k++) 
        printf("%d\t", C[i][k]); 
 
    return 0; 
} 

当我编译时

gcc thread.c -lpthread -lrt 

我收到此错误:

thread.c: In function ‘fnc’: 
thread.c:24:24: error: cannot convert to a pointer type 
         int i=((struct v*)data[l]).i;//Row No 
                        ^ 
thread.c:24:35: error: request for member ‘i’ in something not a structure or union 
         int i=((struct v*)data[l]).i;//Row No 
                                   ^ 
thread.c:25:24: error: cannot convert to a pointer type 
         int j=((struct v*)data[l]).j;//Column No 
                        ^ 
thread.c:25:35: error: request for member ‘j’ in something not a structure or union 
         int j=((struct v*)data[l]).j;//Column No 
                                   ^ 
thread.c: In function ‘main’: 
thread.c:48:20: error: request for member ‘i’ in something not a structure or union 
             data[k].i = i; //assign the row of C for thread to calculate 
                    ^ 
thread.c:49:20: error: request for member ‘j’ in something not a structure or union 
             data[k].j = k; //assign the column of C for thread to calculate 

我相信代码背后的逻辑是正确的,这看起来确实像是一个简单的参数传递问题。我放置了整个代码,因为如果我收到您对问题的评论以及针对所需工作的可能更好的解决方案,我会很高兴。

请您参考如下方法:

这是 @Michi 发布的一个可行的解决方案。您的问题是您将具有相同地址的指针传递给 pthread_create ,而且您还遇到了一些内存分配问题。您必须为二维数组分配内存,并传递到pthread_create

#include <stdio.h> 
#include <pthread.h> 
#include <stdlib.h> 
#include <string.h> 
 
#define N 3 
#define n 3 
 
struct v 
{ 
    size_t i; 
    size_t j; 
}; 
 
double A[N][N] = {{1.0, 2.0, 4.0}, {3.0, 4.0, 5.0}, {4.0, 5.0, 7.0}}; 
double B[N][N] = {{2.0, 3.0, 9.0}, {4.0, 5.0, 7.0}, {2.0, 3.0, 9.0}}; 
double C[N][N]; 
 
static void * multiplication(void *arg){ 
    struct v *data = (struct v *)arg; 
 
    size_t l; 
    for(l=0; l < N; l++) 
    { 
        size_t i=(data[l]).i; 
        size_t j=(data[l]).j; 
        double sum=0; 
        size_t d; 
 
        for (d = 0; d < N; d++) 
        { 
            sum = sum + A[i][d]*B[d][j]; 
        } 
 
        C[i][j] = sum; 
        sum = 0; 
    } 
    return 0; 
} 
 
int main(void) 
{ 
    pthread_t threads[n]; 
    size_t i, k; 
 
    struct v **data; 
    data = (struct v **)malloc(n * sizeof(struct v*)); 
 
    for(i = 0; i < n; i++) 
    { 
        data[i] = (struct v *)malloc(n * sizeof(struct v)); 
 
        for(k = 0; k < n; k++) 
        { 
            data[i][k].i = i; 
            data[i][k].j = k; 
        } 
 
        pthread_create(&threads[i], NULL, multiplication, data[i]); 
    } 
 
    for(i = 0; i < n; i++) 
    { 
        pthread_join(threads[i], NULL); 
    } 
 
    for (i = 0; i < N; i++) 
    { 
        for (k = 0; k < N; k++) 
        { 
            printf("%lf\t", C[i][k]); 
        } 
 
        printf("\n"); 
 
        free(data[i]); 
    } 
 
    free(data); 
 
    return 0; 
}