2015-03-18 67 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),但每个线程都在读取矩阵的每个部分,而其他线程正在修改矩阵。

相关问题