【问题标题】:ptheard not working on Ubuntu with matrixpthard 不能在带有矩阵的 Ubuntu 上工作
【发布时间】:2021-09-01 21:21:09
【问题描述】:

此代码在 Windows 上正常工作,但在 Ubuntu 上没有给出结果。我该怎么办?

顺便说一下,我是通过虚拟机使用Ubuntu的,但我觉得和它没有关系。

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM_THREADS    4
#define MATRIX_SIZE 4

int  matrixA[MATRIX_SIZE][MATRIX_SIZE];
int  matrixB[MATRIX_SIZE][MATRIX_SIZE];
int  matrixSerial[MATRIX_SIZE][MATRIX_SIZE]={0};
int  matrixParallel[MATRIX_SIZE][MATRIX_SIZE]={0};
//Randomize matrix A and B
void randomizeMatrixAandMatrixB()
{
    int i,j;
    for(i=0; i<MATRIX_SIZE;i++)
        for(j=0; j<MATRIX_SIZE;j++)
        {
            matrixA[i][j]=rand() % 10;
            matrixB[i][j]=rand() % 10;
        }   
}
//this void is Matrix2D
void printMatrix2D(int mat2D[MATRIX_SIZE][MATRIX_SIZE])
{
    int i, j;
    for (i = 0; i < MATRIX_SIZE; i++)
    {
        for (j = 0; j < MATRIX_SIZE; j++)
        {
            printf("%d ", mat2D[i][j]); 
        }
        printf("\n");
    } 
    printf("\n");   
}

//I created this here serailMatrix
void serialMatrixMultiplication()
{   
    int row, column,i;
    for (row = 0; row < MATRIX_SIZE; row++)
        for (column = 0; column < MATRIX_SIZE; column++)
            for (i = 0; i < MATRIX_SIZE; i++)
                matrixSerial[row][column] += matrixA[row][i] * matrixB[i][column];

}

//int step for multiplyMatrix
int step_i = 0;
void *multiplyMatrix(void*arg )
{   
    int core=step_i++;
    int row, column,i;
    for (row = core * MATRIX_SIZE / 4; row < (core + 1) * MATRIX_SIZE / 4; row++){
    
        for (column = 0; column < MATRIX_SIZE; column++){
            for (i = 0; i < MATRIX_SIZE; i++) {
                        matrixParallel[row][column] += matrixA[row][i] * matrixB[i][column];
            }
        }
    }
pthread_exit(NULL);
}

//void paraleleling 
void parallelMatrixMultiplication()
{
    pthread_t *thread;
    int i;
    for (i = 0; i < NUM_THREADS; i++) {
        int* p;
        thread=malloc(sizeof(pthread_t));
        pthread_create(thread, NULL, multiplyMatrix, (void*)(p));
    }
}

int main (int argc, char *argv[])
{
    srand(time(0));
    //Randomize
    randomizeMatrixAandMatrixB();
    printf("Matrix A\n");
    printMatrix2D(matrixA);
    printf("Matrix B\n");
    printMatrix2D(matrixB);
    
    
    //Serial Matrix Multiplication
    serialMatrixMultiplication();
    printf("Serial Multiplication\n");
    printMatrix2D(matrixSerial);
    
    //Parallel Matrix Multiplication
    parallelMatrixMultiplication();
    printMatrix2D(matrixParallel);
    return 0;
}

我应该怎么做才能在虚拟机中运行这些代码?我在代码行中的错误在哪里?由于它在 Windows 上运行良好,而不是在 linux 上,因此它将剩余的值从第一行显示为 0。比如我们在一个 4x4 的矩阵上把它分成 4 个线程,第一行从 0 开始看起来是这样的。我猜它不是在运行线程

For Example:
Serial Multiplaction
144 255 1 2
15 18 5 4
125 14 52 46
14 5 1 3


0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

【问题讨论】:

  • 显然是竞争条件。在parallelMatrixMultiplication(); 之后添加sleep(1),它工作正常(虽然不是说这是一个修复)。
  • int core=step_i++; 代码不尝试互斥也不同步。例如,多个线程可以为core 获得相同的值 - 代码需要使用互斥(例如,使用互斥锁)以确保针对每个线程以原子方式完成操作。可能还有其他地方需要这样做。

标签: c linux bash multithreading pthreads


【解决方案1】:
  1. parallelMatrixMultiplication() 启动处理线程,然后直接进入printMatrix2D()。您不是在等待线程完成。
  2. 您有内存泄漏,因为您正在重用parallelMatrixMultiplication() 中的thread 变量。你打电话给malloc(),但不是free()

【讨论】:

    【解决方案2】:

    你很幸运它可以在 Windows 上运行。

    您的代码中缺少的是同步。

    在显示结果之前,您必须等待线程完成。您可以使用pthread_join 轻松做到这一点

    //void paraleleling  
    void parallelMatrixMultiplication()
    {
        pthread_t threads[NUM_THREADS];
        int params[NUM_THREADS];
        int i;
        for (i = 0; i < NUM_THREADS; i++) {
            params[i] = i;
            pthread_create(threads+i, NULL, multiplyMatrix, &params[i]);
        }
        for (i = 0; i < NUM_THREADS; i++) {
            pthread_join(threads[i], NULL);
        }
    }
    

    如您所见,我还更改了给multiplyMatrix 的参数以避免使用step_i:在主线程中,准备了一个包含参数的数组。

    //int step for multiplyMatrix
    void *multiplyMatrix(void*arg )
    {   
        int core=*(int*)arg;
        int row, column,i;
        for (row = core * MATRIX_SIZE / 4; row < (core + 1) * MATRIX_SIZE / 4; row++){
        
            for (column = 0; column < MATRIX_SIZE; column++){
                for (i = 0; i < MATRIX_SIZE; i++) {
                            matrixParallel[row][column] += matrixA[row][i] * matrixB[i][column];
                }
            }
        }
        pthread_exit(NULL);
    }
    

    最后一件事:如果两个不同的线程可以修改matrixParallel 中的同一个单元格,那么添加一些互斥锁是个好主意。

    【讨论】:

    • 我用这段代码解决了我的问题,非常感谢。
    猜你喜欢
    • 2019-12-30
    • 2013-07-25
    • 1970-01-01
    • 2022-09-07
    • 1970-01-01
    • 2011-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多