c - C 中带有 pthreads 的两个矩阵的乘积

标签 c pointers matrix struct pthreads

我对 C Pthreaded 程序有疑问。我必须计算两个矩阵 m1(nr1 行和 nc1 列)和 m2(nr2 行和 nc2列)。 我创建 nr1 * nc2 线程运行时传递给每个线程 m1 的行数和 m2 的列数相乘。线程,将结果保存在另一个矩阵中。代码是这样的:

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



struct prodmat{
int  row;
int  col;
};

int number;
double **dmat1;
double **dmat2;
double **dmatprod;

void ** allocaM2d (int nr, int nc, int dim);
void prodmat(double ** a,  double ** b, double ** c, int nr1, int nc1nr2,
               int nc2);

void * prodthread(struct prodmat * prod){

pthread_detach (pthread_self ());
//printf("THREAD");
 int r,c,k;
 r = prod->row;
 c = prod->col;

 printf("Thread for product of row = %i, column = %i and number = %i\n",r,c,number);


      for (k=0; k<number; k++){
        //dmatprod[r][c] += dmat1[r][k]*dmat2[k][c];
        printf("product of dmat1[%i][%i]=%i * dmat2[%i][%i] = %i\n",r,k,dmat1[r][k],k,c, dmat2[k][c]);     

         }

}


int main(void) {

int  nr1, nc1, nr2, nc2, dim, i, j, k,r,c;


printf("Rows and Columns of the first matrix: ");
scanf ("%d%d",&nr1,  &nc1);
do {
  printf("Rows and Columns of the second matrix\n");
  printf("The number of rows must be equal to nc1 ");
  scanf ("%d%d",&nr2,  &nc2);
} while (nr2 != nc1);




number = nr2;
//  dynamic allocation 

dim = sizeof(double);

dmat1 = (double **) allocaM2d(nr1,  nc1, dim);
dmat2 = (double **) allocaM2d(nr2,  nc2, dim);
dmatprod = (double **) allocaM2d(nr1, nc2, dim);



// in this for i create m1 and m2 and then i print these
k=0;
for(i=0;i<nr1;i++)
  for(j=0;j<nc1;j++)
    dmat1[i][j] = k++;

for(i=0;i<nr1;i++){
  for(j=0;j<nc1;j++)
    printf("%lf ", dmat1[i][j]);
  printf("\n");
}

printf("\n");
k=0;
for(i=0;i<nr2;i++)
  for(j=0;j<nc2;j++)
    dmat2[i][j] = k++;

for(i=0;i<nr2;i++){
  for(j=0;j<nc2;j++)
    printf("%lf ", dmat2[i][j]);
  printf("\n");
}



//This is the cycle where i create the threads
r=0; c=0;
for(r=0; r<nr1 ; r++)
{



  for(c=0; c<nc2; c++){

   struct prodmat * prod; prod= malloc(sizeof(struct prodmat *));
   pthread_t * th; th= malloc(sizeof(pthread_t *)); 

   prod->row = r;
   prod->col = c;

   pthread_create(th,NULL,prodthread,prod);  
  }


}
/*
prodmat( dmat1, dmat2, dmatprod, nr1, nc1, nc2);

printf("\n");
for(i=0;i<nr1;i++){
  for(j=0;j<nc2;j++)
    printf("%lf ", dmatprod[i][j]);
  printf("\n");
}
*/


//is not important this sleep(100). I will replace in future.
sleep(100);
}

/************************************************************/

void ** allocaM2d (int nr, int nc, int dim){
int i;
void ** m;
char * vd;  //  byte pointer

m = (void **) malloc(nr * sizeof(void *));
vd = (char *) malloc(nr * nc * dim);

for(i=0;i<nr;i++)
  m[i] = &vd[i * nc * dim];

return (void **) m; // return matrix pointer        
}

然后我收到 m1 和 m2 的打印品以及产品的打印品,如下所示:

   0.000000 1.000000 2.000000 3.000000 4.000000 
   5.000000 6.000000 7.000000 8.000000 9.000000 
   10.000000 11.000000 12.000000 13.000000 14.000000 
   15.000000 16.000000 17.000000 18.000000 19.000000 

   0.000000 1.000000 2.000000 3.000000 
   4.000000 5.000000 6.000000 7.000000 
   8.000000 9.000000 10.000000 11.000000 
   12.000000 13.000000 14.000000 15.000000 
   16.000000 17.000000 18.000000 19.000000 

    Thread for product of row = 3, column = 2 and number = 5
    product of dmat1[3][0]=0 * dmat2[2][0] = 0
    product of dmat1[3][1]=1 * dmat2[2][0] = 0
    product of dmat1[3][2]=2 * dmat2[2][0] = 0
    product of dmat1[3][3]=3 * dmat2[2][0] = 0
    product of dmat1[3][4]=4 * dmat2[2][0] = 0

但是,在第二部分中,如果 m2 从未被初始化(即使在第一部分中打印显示不同),似乎也是如此。

已解决: 正确的代码是这样的:

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



struct prodmat{
int  row;
int  col;
};

int number;
double **dmat1;
double **dmat2;
double **dmatprod;

void ** allocaM2d (int nr, int nc, int dim);
void prodmat(double ** a,  double ** b, double ** c, int nr1, int nc1nr2,
               int nc2);

void * prodthread(struct prodmat * prod){

pthread_detach (pthread_self ());
//printf("THREAD");
 int r,c,k;
 r = prod->row;
 c = prod->col;

 //printf("Thread for product of row = %i, column = %i \n",r,c);


      for (k=0; k<number; k++){
        dmatprod[r][c] += dmat1[r][k]*dmat2[k][c];
        //printf("product of dmat1[%i][%i]=%lf * dmat2[%i][%i] = %lf\n",r,k,dmat1[r][k],k,c, dmat2[k][c]);     

         }

  pthread_exit(pthread_self ());

}

void * printer(struct prodmat * prod){

pthread_detach (pthread_self ());
//printf("THREAD");
 int r,c,i,j;
 r = prod->row;
 c = prod->col;

 //printf("Thread for product of row = %i, column = %i \n",r,c);

    printf("\n\n --> PRODUCT: \n\n");
      for(i=0;i<r;i++){
         for(j=0;j<c;j++)
          printf("%lf ", dmatprod[i][j]);
          printf("\n");
         } 

  printf("\n\n ");
  pthread_exit(pthread_self ());

}

int main(void) {

int  nr1, nc1, nr2, nc2, dim, i, j, k,r,c;


printf("Rows and Columns of the first matrix: ");
scanf ("%d%d",&nr1,  &nc1);
do {
  printf("Rows and Columns of the second matrix\n");
  printf("The number of rows must be equal to nc1 ");
  scanf ("%d%d",&nr2,  &nc2);
} while (nr2 != nc1);




number = nr2;
//  dynamic allocation 

dim = sizeof(double);

dmat1 = (double **) allocaM2d(nr1,  nc1, dim);
dmat2 = (double **) allocaM2d(nr2,  nc2, dim);
dmatprod = (double **) allocaM2d(nr1, nc2, dim);

k=0;
for(i=0;i<nr1;i++)
  for(j=0;j<nc1;j++)
    dmat1[i][j] = k++;

for(i=0;i<nr1;i++){
  for(j=0;j<nc1;j++)
    printf("%lf ", dmat1[i][j]);
  printf("\n");
}

printf("\n");
k=0;
for(i=0;i<nr2;i++)
  for(j=0;j<nc2;j++)
    dmat2[i][j] = k++;

for(i=0;i<nr2;i++){
  for(j=0;j<nc2;j++)
    printf("%lf ", dmat2[i][j]);
  printf("\n");
}


r=0; c=0;
for(r=0; r<nr1 ; r++)
{



  for(c=0; c<nc2; c++){

   struct prodmat * prod; prod= malloc(sizeof(struct prodmat));
   pthread_t * th; th= malloc(sizeof(pthread_t )); 

   prod->row = r;
   prod->col = c;

   pthread_create(th,NULL,prodthread,prod);  
  }


}

sleep(1);
 struct prodmat * prod; prod= malloc(sizeof(struct prodmat));
 pthread_t * th; th= malloc(sizeof(pthread_t )); 

 prod->row = nr1;
 prod->col = nc2;

 pthread_create(th,NULL,printer,prod);  

/*
prodmat( dmat1, dmat2, dmatprod, nr1, nc1, nc2);

printf("\n");
for(i=0;i<nr1;i++){
  for(j=0;j<nc2;j++)
    printf("%lf ", dmatprod[i][j]);
  printf("\n");
}
*/


pthread_exit(pthread_self ());



}

/************************************************************/

void ** allocaM2d (int nr, int nc, int dim){
int i;
void ** m;
char * vd;  //  byte pointer

m = (void **) malloc(nr * sizeof(void *));
vd = (char *) malloc(nr * nc * dim);

for(i=0;i<nr;i++)
  m[i] = &vd[i * nc * dim];

return (void **) m; // return matrix pointer        
}

对于 ex 的 5x5 和 5x5 输入,这会产生:

0.000000 1.000000 2.000000 3.000000 4.000000 
5.000000 6.000000 7.000000 8.000000 9.000000 
10.000000 11.000000 12.000000 13.000000 14.000000 
15.000000 16.000000 17.000000 18.000000 19.000000 
20.000000 21.000000 22.000000 23.000000 24.000000 

0.000000 1.000000 2.000000 3.000000 4.000000 
5.000000 6.000000 7.000000 8.000000 9.000000 
10.000000 11.000000 12.000000 13.000000 14.000000 
15.000000 16.000000 17.000000 18.000000 19.000000 
20.000000 21.000000 22.000000 23.000000 24.000000 


 --> PRODUCT: 

150.000000 160.000000 170.000000 180.000000 190.000000 
400.000000 435.000000 470.000000 505.000000 540.000000 
650.000000 710.000000 770.000000 830.000000 890.000000 
900.000000 985.000000 1070.000000 1155.000000 1240.000000 
1150.000000 1260.000000 1370.000000 1480.000000 1590.000000 

最佳答案

您的产品 printf 不正确。

printf("product of dmat1[%i][%i]=%i * dmat2[%i][%i] = %i\n",r,k,dmat1[r][k],k,c, dmat2[k][c]);
//                                ^ wrong              ^ wrong

矩阵中的内容是 double float ,您应该使用 %f 或其他合适的浮点格式说明符。

关于c - C 中带有 pthreads 的两个矩阵的乘积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43136047/

相关文章:

c++ - 结构/对象内的存储顺序

r - 计算R中逻辑矩阵的列数

java - 矩阵到图形表示 - java

c - 是否有推荐的整数类型来存储标准 C 中的函数指针

c++ - C/C++ XMPP 库适用于 Android (NDK) 和 iOS

c++ - 将套接字重新绑定(bind)到不同的接口(interface)

c - 更改指针 (C) 时数组元素会发生什么?

将日期数组转换为整数

c# - 统一: Rotate gizmo with an offset of 45

c - 如何在C中递增/递减十六进制值