2015-03-18 69 views
1

(添加的問題完整性正確的代碼)我已經寫到找到的所有點在圖中的弗洛伊德,沃肖爾最短路徑矩陣程序(輸入爲矩陣)所有其他點圖形。代碼如下。我的問題與我相信的pthreads/LowestTerm函數有關。對於小型矩陣,該程序運行得很好。但是,對於大型矩陣和大量的線程(8ish很大),我得到一個分段錯誤錯誤,沒有提供其他信息。編譯顯示沒有問題。任何人都會看到代碼與書寫方式不符的地方?難道是線程都試圖同時訪問矩陣,即使它們專用於矩陣的特定行嗎?感謝您的任何幫助和建議。問題與並行線程,不知道這裏的錯誤是

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <semaphore.h> 

int n, **C, **D, printthread;     /* Variable declarations */ 
pthread_t *threads; 
pthread_cond_t condprint; 
pthread_mutex_t mutexprint; 
long thread, threadcount; 

printthread = 0; 

void *LowestTerm(void* rank); 

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

    int i, j;      /* Variable declarations */ 
    char filename[50]; 

    threadcount = atoi(argv[1]); 
    threads = malloc (threadcount * sizeof(pthread_t)); 

    printf("Enter filename: ");    /* User enters filename for directed graph values */ 
    scanf("%s", filename); 

    FILE *fp = fopen(filename, "r"); 

    if (fp == NULL) {     /* Check whether file exists or not */ 
     printf("File does not exist"); 
     return 1; 
    } 

    fscanf(fp, "%d", &n);     /* Obtain size of matrix */ 

    C = (int **)malloc(n * sizeof(int *));   /* Allocate memory for matrix arrays */ 
    D = (int **)malloc(n * sizeof(int *)); 

    for (i = 0; i < n; i++) {    /* Allocate matrices into 2D arrays */ 
     C[i] = (int *)malloc(n * sizeof(int)); 
     D[i] = (int *)malloc(n * sizeof(int)); 
    } 


    for (i = 0; i < n; i++) {    /* Read matrix from file into C array */ 
     for (j = 0; j < n; j++) { 
      fscanf(fp, "%d", &C[i][j]); 
     } 
    } 

    printf("Cost Adjacency Matrix:\n");   /* Print cost adjacency matrix */ 
    for (i = 0; i < n; i++) { 
     for (j = 0; j < n; j++) { 
      printf("%d ", C[i][j]); 
     } 
     printf(" \n"); 
    } 

    for (i = 0; i < n; i++) {    /* Copy matrix from C array into D array */ 
     for (j = 0; j < n; j++) { 
      D[i][j] = C[i][j]; 
     } 
    } 

    printf("Distance matrix:\n");    /* Print Distance matrix label */ 



    for (thread = 0; thread < threadcount; thread++) { /* Create threads for making and printing distance matrix */ 
     pthread_create(&threads[thread], NULL, LowestTerm, (void*) thread); 
    } 
    for (thread = 0; thread < threadcount; thread++) { /* Join threads back together */ 
     pthread_join(threads[thread], NULL); 
    } 

    pthread_cond_destroy (&condprint); 
    pthread_mutex_destroy (&mutexprint); 
    free(threads); 
    pthread_exit(NULL); 

} 


void *LowestTerm(void* rank) { 

    int i, j, k;      /* Variable declarations */ 
    long mythread = (long) rank; 

    int istart = ((int)mythread * n)/(int)threadcount; /* Create matrix row start and finish parameters for each thread */ 
    int ifinish = ((((int)mythread + 1) * n)/(int)threadcount); 

    for (k = 0; k < n; k++) {    /* Find shortest path for each value in each row for each of designated thread's rows */ 
     for (i = istart; i < ifinish; i++) { 
      for (j = 0; j < n; j++) { 
       if (D[i][j] > D[i][k] + D[k][j]) { 
        D[i][j] = D[i][k] + D[k][j]; 
       } 
      } 
     } 
    } 

    pthread_mutex_lock (&mutexprint);   /* Print distance matrix portion for each thread */ 
    while (printthread != mythread) { 
     pthread_cond_wait (&condprint, &mutexprint); 
    } 
    for (i = istart; i < ifinish; i++) { 
     printf("Thread %d: ", mythread); 
     for (j = 0; j < n; j++) { 
      printf("%d ", D[i][j]); 
     } 
     printf(" \n"); 
    } 
    printthread++; 
    pthread_cond_broadcast (&condprint); 
    pthread_mutex_unlock (&mutexprint); 


    return NULL; 
} 

回答

2

問題來源於此行:

int i, j, k, n, totaln, **C, **D; 

由於I,J和K計數器在全球範圍內宣佈他們是由所有線程共享。

如果線程是上下文切換,而內循環的內部,另一個線程可以遞增這些計數器過去陣列的端中的一個。當原始線程喚醒時,它會嘗試讀取數組的末尾,這是未定義的行爲,並可能導致段錯誤。

您可以通過計數器變量的範圍限制到LowestTerm功能解決這個問題。實際上,需要在全局範圍內定義的唯一變量是** D,n和線程數;而n和threadcount並不需要共享,它們可以作爲參數傳遞給LowestTerm。

+0

非常感謝!這很有道理! – 2015-03-19 03:52:48

0

j兩者並從0k環路n,所以術語D[k][j]可以是在基體中的任何元件。因此,雖然只寫入特定的行(索引爲i),但每個線程都在讀取矩陣的每個部分,而其他線程正在修改矩陣。

相關問題