如何按顺序从pthreads中的每个线程打印?

How to print from each thread in pthreads in order?

我正在为 class 开发一个程序,它采用 Floyd-Warshall 有向图(由矩阵表示)并为图中的每个节点创建一个新的距离矩阵,拆分创建的工作使用 pthreads 的线程之间的新矩阵。我觉得我在最后是对的,我可以得到矩阵来形成和打印,但我似乎无法弄清楚如何让距离矩阵按顺序打印(首先由线程 0 创建的矩阵行,然后线程 1、线程 2 等)。我使用互斥体来允许每个线程不间断地一起打印它的部分,我只是无法让线程按顺序打印。

我想知道那里的 pthread 大师是否会帮助我。提前致谢!

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

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

void *LowestTerm(void* rank);

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

    int i, j, k;                        /* 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 */

    totaln = n * n;

    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");



    for (thread = 0; thread < threadcount; thread++) {
        pthread_create(&threads[thread], NULL, LowestTerm, (void*) thread);
    }
    for (thread = 0; thread < threadcount; thread++) {
        pthread_join(threads[thread], NULL);
    }

    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 */
    for (i = istart; i < ifinish; i++) {
        printf("Thread %d: ", mythread);
        for (j = 0; j < n; j++) {
            printf("%d ", D[i][j]);
        }
        printf(" \n");
    }
    pthread_mutex_unlock (&mutexprint);


    return NULL;
}

最简单的解决方案是让主线程在所有工作线程完成后按您想要的顺序打印整个矩阵。


或者,为了让您的线程按顺序打印,您可以使用一个共享变量来指定下一个要打印的线程(初始化为 0),并与条件变量配对:

pthread_mutex_lock (&mutexprint);           /* Print distance matrix */
while (next_thread != 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");
}

next_thread++;
pthread_cond_broadcast(&condprint);
pthread_mutex_unlock (&mutexprint);

作为一个单独的问题,我不认为你的线程安全地共享 D[] 数组 - 看起来来自 D[k][j] 的读取可能正在读取另一个正在同时写入的位置线程。

since each thread has a parameter that indicates its' rank,
the mutex could be on a global variable that indicates 
which thread/rank is to print next.
initialize it to 0.
each thread reads the global variable, after the thread
is ready to print
when the global variable matches the threads' rank, 
then the thread can:
1) lock the mutex, 
2) print, 
3) increment the global variable, 
4) unlock the mutex
5) call pthread_exit()

BTW: why are thread and threadcount defined as 'long'?
are you expecting there to be more than 4 gig threads?

at the end of function: LowestTerm()
which is a thread function.
the proper exit is not 'return value;'\
but rather phread_exit( value );

'