2015-10-19 160 views
3


多线程我想创建,其通过使用线程计算两个N * N的矩阵的乘法运算的C程序。
我参考启动此代码:Matrix Multiplication using multiple threads但不是对结果矩阵中的每个单元创建N * N个线程,我想创建N个线程做乘法同时在结果矩阵中的每一行都会被计算不同的线程。
我的代码看起来是这样的,到目前为止矩阵乘法在C

#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 

我相信代码背后的逻辑是正确的,这肯定看起来像一个简单的参数传递问题。我把整个代码放在了一起,因为如果我收到你对这个问题的评论,并且为你期望的工作提供了一个更好的解决方案,我会很高兴。 谢谢。

+0

有太多的问题,你应该阅读更多关于转换和你为什么尝试访问** - > **而不是**。**的变量?什么是**我**和** **是什么? – Michi

+0

你是对的,来自C++的老习惯,我删除了 - >。 我也试图解释i和j在评论 –

+0

既然你修正了一些编译器错误,你应该修改你的问题,以消除那些错误。 – Adam

回答

0

您好我已经实现使用3×3 thread.The代码3×3的矩阵乘法可以为N * N.The代码被修改是自解释的。

*header*/ 
#include <pthread.h> 
#include <stdio.h> 
#include<stdlib.h> 
/*macro*/ 
#define NUM_THREADS  9 
/*I have defined the structure here to pass the multiple arguments 
when creating threads*/ 
/*structure declaration*/ 
struct thread_data 
{ 
    int element1[3];//passing the element of one matrix 
    int element2[3];//passing the element of other matrix 
    int sum;//storing the result of multiplication 
}thread_data_array[NUM_THREADS]; 
/** 
* @brief finds matrix multiplication function 
* param [in] : accepts the thread arguments 
* 
* @return void pointer 
*/ 
void *multiplication(void *threadarg) 
{ 
    int i; 
    struct thread_data *my_data; 
    my_data = (struct thread_data *) threadarg;/*type cast the 
void pointer to the struct thread*/ 
    //pointer 
    my_data->sum=0; 
    for(i=0;i<3;i++){/*multiply and add each element 
of 1st matrix to 2nd matrix*/ 
     my_data->sum=my_data->sum 
      +((my_data->element1[i])*(my_data->element2[i])); 
    } 
} 
/*main*/ 
int main (int argc, char *argv[]) 
{ 
    pthread_t threads[NUM_THREADS]; 
    int rc; 
    int t; 
    int matrix_b[3][3]={{156,223,345},{456,5678,656},{712,811,922}}; 
//to store the matrix 
    int matrix_a[3][3]={{123,278,335},{437,547,656},{734,832,944}}; 
    int ans[9]; 
    int i,j,count,z,k,l,q; 
    t=i=j=z=count=k=q=l=0; 
/* 
suppose the matrices are 
1 2 3  1 2 3 
4 5 6  1 2 3 
7 8 9  1 2 3 
so to perform the multiplication 
row 1 2 3 will be multiplied too column 
111 222 333 respectively. 
so 123 shold be stored in 3 spreate threads 
and 111 222 333 should be stored in 3 seprate threads 
123 111 should be in common thread 
123 222 should be in common thread 
123 333 should be in common thread 
in this way below logic i have 
writtten. 
It is hard to understand at first glance.. 
so enjoy!!!!!! 
*/ 
    while(z<3){ 
      for(count=0;count<3;count++){/*store the each row of 
first matrix 3 times in 3 seprate threads*/ 
       for(j=0;j<3;j++) 
        thread_data_array[t].element1[j] 
         = matrix_a[i][j]; 
       t++; 
      } 
/*store the each column of the second matrix in the spreate threads*/ 
      for(k=0;k<3;k++){ 
       for(l=0;l<3;l++) 
        thread_data_array[q].element2[l] 
         = matrix_b[l][k]; 
       q++; 
      } 
      i++; 
      z++; 
    } 
/*we have total 9 element in resultant matrix,so to create it we should 
create 9 threads*/ 
    for(t=0; t<NUM_THREADS; t++){ 
     rc =pthread_create (&threads[t], NULL, multiplication, 
       (void *) &thread_data_array[t]); 
/*we are passing the function pointer and 

the pointer to structure as the argument,since we want to pass multiple argumen 
ts we       are passing the structure poi 
nter as the arguments.*/ 
     if (rc){//if rc is not 0,error is there 
      printf("ERROR; return code from() is %d\n", rc); 
      exit(-1); 
     } 
    } 
/* 
NAME   

     pthread_join - join with a terminated thread 

SYNOPSIS   

     #include <pthread.h> 

     int pthread_join(pthread_t thread_here, void **retval); 

     Compile and link with -pthread. 

DESCRIPTION   

    The pthread_join() function waits for the thread specified by thread_here 
    to terminate. If that thread has already terminated, then 
    pthread_join() returns immediately. The thread specified by thread 
    must be joinable. 
*/ 
    for (i = 0; i < 9; i++)/*to wait for all the threads to complete*/ 
      pthread_join(threads[i], NULL); 
    printf("%d %d %d\n",thread_data_array[0].sum,thread_data_array[1].sum,thread_data_array[2].sum); 
    printf("%d %d %d\n",thread_data_array[3].sum,thread_data_array[4].sum,thread_data_array[5].sum); 
    printf("%d %d %d\n",thread_data_array[6].sum,thread_data_array[7].sum,thread_data_array[8].sum); 
} 
+0

OP明确要求N个线程用于NxN矩阵,并且链接了一个问题,该问题已经涵盖了用于NxN矩阵的NxN个线程的情况。除了硬编码一堆其他问题作为变量留下的内容之外,这并没有真正起作用。 – ShadowRanger

0

这里是由@Michi发布的工作解决方案。您的问题是,您将同一地址的指针传递给pthread_create,同时您也遇到了内存分配问题。您必须为两个dimmentional阵列分配内存,并传入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; 
}