1

以下代码试图完成的只是计算 A 和 B 的矩阵乘法以获得矩阵 C。它使用 nXn 个线程独立计算 C 的每个条目。所以代码适用于 Cygwin,但不适用于 linux。我通过 Pthread_join 调用不断获得段默认值。

#define _REENTRANT // Make sure the library functions are MT (muti-thread) safe
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define BUFFER_SIZE 512

// Declare a structure data type that will be used to pass arguments to the worker threads
typedef struct args_for_thread_t{
         int *rowA;
         int rowIdx;
         int *columnB;
         int columnIdx;
         int **matrixC;

} ARGS_FOR_THREAD;
/* Global Variables */
int numRows,numColumns;

/*Function Prototype*/
void *computeC(void *this_arg);
void printMatrix(int** matrix,int numRows,int numColumns);

int main(void){
    const char filename[] = "input_data.txt";
    FILE *file = fopen(filename,"r");
    char *delims = " ";
    int **matrixA,**matrixB,**matrixC;
    int flagB = 0; //Indicate wether the program should process matrixB
    int i,j;

    if (file){
        char line[BUFFER_SIZE];
        int rowIdx = 0;
        while (fgets(line,sizeof(line), file)){
            char substr[BUFFER_SIZE], *result;
            //fputs(line,stdout);
            result = strtok(line, delims);
            int columnIdx = 0;

            //Once we reach a line break, we start the processing of matrix B
            if (!strcmp(line,"\n")){
                flagB = 1;
                rowIdx = 0; //Reset the rowIdx
                continue; //Skip the new line, and start to read data into matrix B
            }
            while (result != NULL){
                if (!strcmp(result,"ROWS")){ //To retrieve the number of rows
                  result = strtok(NULL,delims);
                  numRows = atoi(result);
                  matrixA = (int **) malloc(numRows*sizeof(int*));
                  matrixB = (int **) malloc(numRows*sizeof(int*));
                  matrixC = (int **) malloc(numRows*sizeof(int*));
                  rowIdx = -1;
                  result = strtok(NULL,delims);
                }
                else if (!strcmp(result,"COLUMNS")){//To retrieve the number of Columns
                  result = strtok(NULL,delims);
                  numColumns = atoi(result);
                  for (i=0;i<numRows;i++){ //Malloc the columns
                    matrixA[i] = (int *) malloc(numColumns*sizeof(int));
                    matrixB[i] = (int *) malloc(numColumns*sizeof(int));
                    matrixC[i] = (int *) malloc(numColumns*sizeof(int));
                  }
                  rowIdx = -1;
                  result = strtok(NULL,delims);
                }
                else if (!flagB){ //Processing Matrix A
                    matrixA[rowIdx][columnIdx] = atoi(result);
                    columnIdx++;
                    result = strtok(NULL,delims);
                }
                else if (flagB){ //Processing Matrix B
                    matrixB[rowIdx][columnIdx] = atoi(result);
                    columnIdx++;
                    result = strtok(NULL,delims);
                }
            }
            rowIdx++;
        }
    }
    else{
        printf("No Such File exists!\n");
    }
    //At this point, matrix A and matrix B are both ready for computation. We will start to compute the product of the two matrices
    int num_threads = numRows*numColumns; //The toal number of worker threads
    pthread_t *worker_thread = (pthread_t *) malloc(sizeof(pthread_t)*num_threads);
    ARGS_FOR_THREAD *args_for_thread;


    for(i = 0; i < numRows; i++){
        for(j = 0; j < numColumns; j++){
            args_for_thread = (ARGS_FOR_THREAD *)malloc(sizeof(ARGS_FOR_THREAD)); // Allocate memory for the structure that will be used to pack the arguments
            args_for_thread-> rowA = matrixA[i]; 
            //We need to allocate the corresponding column in B for multiplication
            int k;
            args_for_thread->columnB =(int *) malloc(sizeof(int)*numRows);
            for (k=0;k<numRows;k++){
                args_for_thread-> columnB[k] = matrixB[k][j];
            }
            //rowIdx and columnIdx gives the corresponding entry for matrix C
            args_for_thread-> rowIdx = i;
            args_for_thread-> columnIdx = j;
            args_for_thread-> matrixC = matrixC;            
            if((pthread_create(&worker_thread[i], NULL, computeC, (void *)args_for_thread)) != 0){
                printf("Cannot create thread \n");
                exit(0);
            }
        }
    }
    // Wait for all the worker threads to finish 
    for(i = 0; i < num_threads; i++)
        pthread_join(worker_thread[i], NULL);
    //Print out the Final Matrix C
    printMatrix(matrixC,numRows,numColumns);
    //Clean up pointers
    for(i = 0; i < numRows; i++){
        free(matrixA[i]);
        free(matrixB[i]);
        free(matrixC[i]);
    }
    free(matrixA);
    free(matrixB);
    free(matrixC);
}
void printMatrix(int** matrix,int numRows, int numColumns){
    int i,j;
    for (i=0;i<numRows;i++){
        for (j=0;j<numColumns;j++){
            printf("%d ",matrix[i][j]);
            if (j==numColumns-1){
                printf("\n");
            }
        }
    }   
}
/* Function that will be executed by all the worker threads. It will compute the i,j entry for column C */
void *computeC(void *this_arg){
    ARGS_FOR_THREAD *arg = (ARGS_FOR_THREAD *) this_arg;
    int rowIdx = arg->rowIdx;
    int columnIdx = arg->columnIdx;
    int *rowA = arg->rowA;
    int *columnB = arg->columnB;
    int **matrixC = arg->matrixC;
    int i;
    int sum = 0;

    for (i=0;i<numRows;i++){  //Compute entry for matrix C. Since A,B are nxn square matrix, we can use either numRows or numColumns as the size
        sum += rowA[i]*columnB[i];
    }
    matrixC[rowIdx][columnIdx] = sum;
    free((void *) arg); // Free up the structure
    pthread_exit(NULL);
}

这里有什么问题?谢谢你。

4

1 回答 1

2

这里:

pthread_create(&worker_thread[i] ...

您创建 i * j 个线程,但您只提供 worker_threads[i] 因此您的程序继续使用相同的 pthread_t 变量。当您尝试使用未定义的 pthread_t 值加入线程时,它稍后会失败。

替换为:

pthread_create(&worker_thread[i*numColumns+j] ...
于 2013-02-08T16:45:55.183 回答