为什么在调试模式下获得不同的值?

时间:2019-06-03 10:10:18

标签: c linux multithreading

我的程序应该使用多线程计算两个给定矩阵的矩阵乘积(乘法)-每个线程计算一列。

问题是-从终端运行它时,得到的零列很少。我使用调试器查看问题出在哪里-但是在调试器上,每次都能正常工作!我不知道问题出在哪里

调试和常规执行时,如何获得不同的值?

我尝试了在线搜索中的一些“简单解决方案”:


重置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 9

1 2 3
4 5 6   
7 8 9

预期输出
30 36 42
66 81 96
  
102 126 150

实际输出:相同,但列为零(每次不同)
谢谢。

1 个答案:

答案 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将其保存。