2015-01-09 49 views
0

我嘗試使用線程來編寫代碼來繁殖矩陣,我有一個問題。我沒有任何警告(我用std = c99 -Wall -pedantic -lpthread編譯),但是當我嘗試使用我的代碼時,我總是在覈心轉儲時遇到問題。 我把我的代碼放在這裏,並要求你提供任何提示,因爲我真的很接近瘋狂。我不知道我能解決什麼問題。我靈感來自this link使用c中的線程乘以矩陣

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#include <time.h> 
#include <stdlib.h> 
#include "sys/types.h" 
#include "unistd.h" 
#include "pthread.h" 

int xA; 
int yA; 
int xB; 
int yB; 
int xC; 
int yC; 
int* mA; 
int* mB; 
int* mC; 
pthread_t* thread; 
int numOfThread; 
int **ap = &mC; 
int **A = &mA; 
int **B = &mB; 

int* allocResultMatrix(int xA, int yB, int *xC, int *yC){ 

    *xC = xA; 
    *yC = yB; 

    return (int *) malloc(sizeof(int) *(*xC * *yC)); 
} 


void makeMatrix(int **ar, int x, int y){ 

    *ar = (int *)malloc(sizeof(int) *(x * y)); 
    int k = -1; 
    int range = 1000;  

    for(int i = 0; i < x; i++){ 
     for(int j = 0; j < y; j++){ 
      (*ar)[++k] = rand() % range; 
     } 
    } 
} 

void* multiply(void* slice){ 

    int s = (int)slice; 
    int from = (s * xA)/numOfThread; 
    int to = ((s+1) * xA)/numOfThread; 


    for (int i = from; i < to; i++){ 
     for (int j = 0; j < yB; j++){ 
      ap[i][j] = 0; 
      for (int k = 0; k < yA; k++){ 
       ap[i][j] += A[i][k]*B[k][j]; 
      } 
     } 
    } 
return 0; 
} 



void printMatrix(int *ar, int x, int y) 
{ 
    int k = -1; 

     for(int i = 0; i < x; i++){ 
     printf(" "); 
      for(int j = 0; j < y; j++){ 
       printf("%9d", ar[++k]); 
      } 
     printf("\n"); 
    } 
    printf("\n"); 

} 

int main(int argc, char* argv[]){ 

    if(argc == 6){ 


    printf("\n"); 



    numOfThread = atoi(argv[1]); 



    if(atoi(argv[2]) > 0 && atoi(argv[2]) <= 10000 && atoi(argv[3]) > 0 && atoi(argv[3]) <= 10000 && atoi(argv[4]) > 0 && atoi(argv[4]) <= 10000 && atoi(argv[5]) > 0 && atoi(argv[5]) <= 10000){ 
     xA = atoi(argv[2]); 
     yA = atoi(argv[3]); 
     xB = atoi(argv[4]); 
     yB = atoi(argv[5]); 

    } 
    else { 
     printf("bad dimensions"); 
     return 0; 
    } 


    if(yA != xB){ 
     printf("yA should be equal with xB\n"); 
     return 0; 
    } 





    srand((unsigned)time(NULL)); 

    makeMatrix(&mA, xA, yA); 
    printMatrix(mA, xA, yA); 
    makeMatrix(&mB, xB, yB); 
    printMatrix(mB, xB, yB); 
    thread = (pthread_t*) malloc(numOfThread * sizeof(pthread_t)); 
    mC = allocResultMatrix(xA, yB, &xC, &yC); 



    for (int iterator = 1; iterator < numOfThread; iterator++){ 


     if (pthread_create (&thread[iterator], NULL, multiply, (void*)iterator) != 0){ 
      perror("er!\n"); 
     free(thread); 
      return 1; 
     } 
} 

multiply(0); 

for (int i = 1; i < numOfThread; i++) 
     pthread_join(thread[i], NULL); 

printf("\nresult\n"); 
    printMatrix(mC, xC, yC); 
free(thread); 
} 

return 0; 
} 
+4

使用調試器來分析核心轉儲。 –

+0

不要打擾寫這段代碼,它已經被寫了很多次。例如:https://code.google.com/p/scalalab/wiki/FastCMatrixMultiplicationUsingPThreads和http://heshans.blogspot.sg/2009/05/matrix-multiplication-using-pthread.html –

回答

0

您正在分配一維數組,並試圖以二維數組的形式訪問它。

尤其是,表達式ap[i][j]multiplyMatrix中假設您有一個指向整數數組的指針數組,但情況並非如此。

如果選中使用Klocwork或類似工具運行代碼,您會注意到ap[i][j]僅對值i=[0..xA*yB]j=0有效。

您可以分配二維數組:

int **allocate(int x, int y) 
{ 
    int **result = malloc(x * sizeof(int*)); 
    for (int i = 0; i < y; i++) 
    { 
     result[i] = malloc(y * sizeof(int)); 
    } 
    return result; 
} 

或者單維乘:

int s = (int)slice; 
int from = (s * xA)/numOfThread; 
int to = ((s+1) * xA)/numOfThread; 

for (int i = from; i < to; i++) 
{ 
    for (int j = 0; j < yB; j++) 
    { 
    ap[i * yB + j] = 0; 
    for (int k = 0; k < yA; k++) 
    { 
     ap[i * yB + j] += A[i * yA + k]*B[k * yB + j]; 
    } 
    } 
} 
+0

好吧,我試過了它仍然無法正常工作。例如第二個選項我得到了:錯誤:無效的操作數到二進制*(有'int *'和'int *') – Mark

+0

好吧,我明白了,謝謝 – Mark