我的程序应该使用多线程计算两个给定矩阵的矩阵乘积(乘法)-每个线程计算一列。
问题是-从终端运行它时,得到的零列很少。我使用调试器查看问题出在哪里-但是在调试器上,每次都能正常工作!我不知道问题出在哪里
调试和常规执行时,如何获得不同的值?
我尝试了在线搜索中的一些“简单解决方案”:
重置linux虚拟机
重置VSCode
而且我没有收到任何错误或内存泄漏,但是我不知道该怎么做
我的代码:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <errno.h>
#include <sys/stat.h>
#include <pthread.h>
int MATRIX_DIM=3; //default
int **RESULT_MAT;
struct calcCol{
int **matA;
int **matB;
int **matC;
int dim;
int i;
};
int ijMult(int **matA, int **matB,int dim, int i, int j);
void* colMatCalc(void* s);
void printMatrix(int **mat);
void getMatrix(int **mat);
void freeMatrices(int **matA, int **matB, int **matC);
void* printThreadId(void* arg){
int i = *(int*)arg;
printf("Thread id: %d \n", i);
pthread_exit(NULL);
}
int main(){
pthread_t tid[MATRIX_DIM];
int args[MATRIX_DIM];
pthread_attr_t attr;
pthread_attr_init(&attr);
printf("Enter enter MATRIX_DIM (number between 1 and 10) \n");
scanf("%d",&MATRIX_DIM);
if(MATRIX_DIM>10 || MATRIX_DIM<1)
MATRIX_DIM=3; //default value
//memory allocation for matrices
int **matA = (int **)malloc(MATRIX_DIM * sizeof(int*));
for(int i = 0; i < MATRIX_DIM; i++) matA[i] = (int *)malloc(MATRIX_DIM * sizeof(int));
int **matB = (int **)malloc(MATRIX_DIM * sizeof(int*));
for(int i = 0; i < MATRIX_DIM; i++) matB[i] = (int *)malloc(MATRIX_DIM * sizeof(int));
RESULT_MAT = (int **)malloc(MATRIX_DIM * sizeof(int*));
for(int i = 0; i < MATRIX_DIM; i++) RESULT_MAT[i] = (int *)malloc(MATRIX_DIM * sizeof(int));
struct calcCol s;
s.matA = matA;
s.matB = matB;
s.matC=RESULT_MAT;
s.dim=MATRIX_DIM;
s.i=0;
printf("Enter elements of first matrix \n");
getMatrix(matA);
printf("Enter elements of second matrix \n");
getMatrix(matB);
for(int i=0 ; i<MATRIX_DIM ; i++)
{
args[i]=i;
s.i=i;
pthread_create(&tid[i], &attr, colMatCalc, &s);
}
for(int i=0 ; i<MATRIX_DIM ; i++)
{
if(pthread_join(tid[i], NULL)!=0)
{
perror("pthread_join faild.");
exit(EXIT_FAILURE);
}
printf("Thread %d is terminated.\n", *(int*)(&args[i]));
}
printf("All threads are terminated!\n");
printf("Product of the matrices: \n");
printMatrix(RESULT_MAT);
freeMatrices(matA, matB, RESULT_MAT);
return 0;
}
//calculating (i,j) of the result matrix
int ijMult(int **matA, int **matB, int dim, int i, int j)
{
int sum = 0;
for(int k = 0 ; k < MATRIX_DIM ; k++)
sum = sum + (matA[i][k]*matB[k][j]);
return sum;
}
//calculating the 'i' column of the result matrix
void* colMatCalc(void* arg)
{
struct calcCol s = *(struct calcCol*)arg;
for(int k = 0 ; k < s.dim ; k++)
s.matC[k][s.i] = ijMult(s.matA, s.matB,s.dim, k, s.i);
return 0;
}
void printMatrix(int **mat)
{
for(int i = 0 ; i < MATRIX_DIM ; i++)
{
for(int j = 0 ; j < MATRIX_DIM ; j++)
{
printf("%d \t", mat[i][j]);
}
printf("\n");
}
}
void getMatrix(int **mat)
{
for(int i=0 ; i<MATRIX_DIM ; i++)
{
for(int j=0 ; j<MATRIX_DIM ; j++)
{
scanf("%d",&mat[i][j]);
}
}
}
void freeMatrices(int **matA, int **matB, int **matC)
{
for(int i=0 ; i < MATRIX_DIM ; i++)
{
free(matA[i]);
free(matB[i]);
free(RESULT_MAT[i]);
}
free(matA);
free(matB);
free(RESULT_MAT);
}
我知道我不需要粘贴整个代码,但是我真的不知道棘手的部分在哪里...再次导致-当我处于调试模式时,它可以正常工作。
输入:
3
1 2 3
4 5 6
7 8 91 2 3
4 5 6
7 8 9预期输出
30 36 42
66 81 96
102 126 150
实际输出:相同,但列为零(每次不同)
谢谢。
答案 0 :(得分:2)
问题出在所有线程之间共享的变量s
,即
s.i=i;
在循环中更新s
时,每个线程将指向s
的最新内容。
您可以做的是对每个线程使用不同的实例,如下所示。
for(int i=0 ; i<MATRIX_DIM ; i++)
{
struct calcCol *s = malloc(sizeof(*s));
s->matA = matA;
s->matB = matB;
s->matC=RESULT_MAT;
s->dim=MATRIX_DIM;
s->i=0;
args[i]=i;
s->i=i;
pthread_create(&tid[i], &attr, colMatCalc, s);
}
这样,当您更新*s
的内容时,它不会影响其他线程的执行。
确保一旦线程执行完毕,就
free
将其保存。