c 线程无法正确打印

问题描述 投票:0回答:1

我正在尝试用 C 语言实现一个带有一些线程的简单程序。具体来说,我希望每个线程只读取 CSV 文件的一部分(每行仅包含四个浮点数)并将读取的值放入矩阵中。因此,每个线程都有自己的矩阵,它们将从分配给它的行中读取的值放入其中。我能够做到这一点,但是当我尝试从每个线程打印每个矩阵时,输出很奇怪,因为某些线程与打印重叠。我认为这是一个并发问题,但我不知道并发是在打印控制台上还是在访问文件 CSV 中,所以实际上在这一点上,我不知道 CSV 行中的值是否正好加载到矩阵中。我把代码和输出都写在这里了。有人可以帮我吗?

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

#define NTHREADS 15
#define NTRAIN 135
#define NFEATURES 4
#define X_TRAIN_PATH "C:/Users/tecnico/Desktop/UniME/Materie/HPC/MPI/Programs/Multithreading/X_train.csv"

void checkFile(FILE *f) {
    if (f == NULL) {
        printf("Error while reading file\n");
        exit(1);
    }
}

float *getFloatMat(int m, int n) {
    float *mat = NULL;
    mat = (float *)calloc(m * n, sizeof(float));

    return mat;
}

float *initFeatures(char path[], int start_row, int end_row) {
    int index = 0;
    FILE *f = NULL;
    float *mat = NULL;

    mat = getFloatMat(end_row - start_row + 1, NFEATURES);

    f = fopen(path, "r");
    checkFile(f);

    // Skippa le righe prima di start_row
    for (int i = 0; i < start_row; i++)
        while (fgetc(f) != '\n')
            ;

    // Leggi i dati dalla riga start_row alla riga end_row
    for (int i = start_row; i <= end_row; i++) {
        for (int j = 0; j < NFEATURES; j++) {
            fscanf(f, "%f%*c", &mat[index]);
            index++;
        }
    }

    fclose(f);
    return mat;
}

struct ThreadData {
    int thread_id;
    int start_row;
    int end_row;
    float *x_train;
};

void *threadFunction(void *arg) {
    struct ThreadData *data = (struct ThreadData *)arg;

    // Inizializza la matrice per il thread corrente
    data->x_train = initFeatures(X_TRAIN_PATH, data->start_row, data->end_row);

    // Stampa la matrice per il thread corrente
    printf("Thread %d:\n", data->thread_id);
    for (int i = 0; i <= data->end_row - data->start_row; i++) {
        for (int j = 0; j < NFEATURES; j++) {
            printf("%.2f ", data->x_train[i * NFEATURES + j]);
        }
        printf("\n\n");
    }

    // Libera la memoria allocata per la matrice
    free(data->x_train);

    pthread_exit(NULL);
}

int main(int argc, char const *argv[]) {
    pthread_t threads[NTHREADS];
    struct ThreadData thread_data[NTHREADS];

    int rows_per_thread = NTRAIN / NTHREADS;
    
    // Creazione e avvio dei thread
    for (int i = 0; i < NTHREADS; i++) {
        thread_data[i].thread_id = i;
        thread_data[i].start_row = i * rows_per_thread + 1;
        thread_data[i].end_row = (i + 1) * rows_per_thread;
        pthread_create(&threads[i], NULL, threadFunction, (void *)&thread_data[i]);
    }

    // Attesa della terminazione dei thread
    for (int i = 0; i < NTHREADS; i++) {
        pthread_join(threads[i], NULL);
    }

    return 0;
}

这是输出:

主题 8: 6.00 2.70 5.10 1.60

6.10 3.00 4.90 1.80

5.90 线程 13: 5.40 3.40 1.50 0.40

5.50 3.50 1.30 0.20

6.70 3.00 5.20 2.30

5.50 2.40 3.80 1.10

4.80 3.40 1.90 0.20

4.60 线程 9: 6.00 3.60 1.00 0.20

5.20 3.50 1.50 0.20

4.90 3.00 1.40 0.20

5.40 3.00 4.50 1.50

3.00 4.80 1.80

6.30 2.70 4.90 1.80

6.40 2.90 4.30 1.30

5.10 3.50 1.40 0.30

6.60 2.90 4.60 1.30

6.80 2.80 4.80 1.40

5.40 3.90 1.70 0.40

5.20 3.40 1.40 0.20

4.80 3.00 1.40 0.30

主题 5: 4.80 3.00 1.40 0.10

5.80 2.80 5.10 2.40

5.80 2.70 4.10 1.00

4.90 2.40 3.30 1.00

6.20 2.80 4.80 1.80

5.00 3.40 1.50 0.20

6.80 3.00 5.50 2.10

5.60 2.50 3.90 1.10

5.60 2.80 4.90 2.00

线程 0: 4.80 线程 1: 3.40 1.60 0.20

5.80 2.70 3.90 1.20

6.70 3.30 5.70 2.50

6.10 3.00 4.60 1.40

6.40 3.20 5.30 2.30

7.30 2.90 6.30 1.80

5.70 2.80 4.10 1.30

5.50 4.20 1.40 0.20

6.70 3.10 5.60 2.40

主题 4: 5.80 2.60 4.00 1.20

5.60 3.00 4.10 1.30

5.50 2.50 4.00 1.30

5.80 2.70 5.10 1.90

5.00 3.30 1.40 0.20

5.10 2.50 3.00 1.10

4.90 3.10 1.50 0.10

5.10 3.80 1.90 0.40

5.60 2.70 4.20 1.30

主题 11: 6.40 2.70 5.30 1.90

5.70 3.80 1.70 0.30

6.90 3.10 5.40 2.10

7.70 2.60 6.90 2.30

6.10 2.80 4.70 1.20

6.30 3.40 5.60 2.40

7.70 3.00 6.10 2.30

6.80 3.20 5.90 2.30

4.60 3.40 1.40 0.30

3.00 5.10 1.80

5.50 2.30 4.00 1.30

5.70 2.50 5.00 2.00

6.50 3.00 5.50 1.80

5.90 3.20 4.80 1.80

6.10 2.60 5.60 1.40

6.90 3.10 5.10 2.30

主题 2: 6.00 3.40 4.50 1.60

5.60 3.00 4.50 1.50

5.40 3.90 1.30 0.40

6.90 3.10 4.90 1.50

4.90 2.50 4.50 1.70

6.40 2.80 5.60 2.10

6.00 2.90 4.50 1.50

5.00 2.30 3.30 1.00

7.20 3.60 6.10 2.50

6.70 3.00 5.00 1.70

5.40 3.40 1.70 0.20

6.10 2.90 4.70 1.40

5.00 3.00 1.60 0.20

5.70 3.00 4.20 1.20

5.00 3.50 1.60 0.60

5.20 2.70 3.90 1.40

6.90 3.20 5.70 2.30

7.40 2.80 6.10 1.90

主题 6: 5.10 3.40 1.50 0.20

5.20 4.10 1.50 0.10

6.30 2.90 5.60 1.80

6.70 3.30 5.70 2.10

5.70 2.80 4.50 1.30

7.10 3.00 5.90 2.10

6.40 3.10 5.50 1.80

7.20 3.20 6.00 1.80

6.00 2.20 4.00 1.00

主题 3: 5.10 3.80 1.60 0.20

4.50 2.30 1.30 0.30

4.90 3.10 1.50 0.10

6.30 3.30 4.70 1.60

4.40 3.20 1.30 0.20

6.30 3.30 6.00 2.50

7.20 3.00 5.80 1.60

4.80 3.10 1.60 0.20

6.30 2.50 5.00 1.90

主题 14: 5.00 3.40 1.60 0.40

6.50 3.00 5.20 2.00

5.00 3.50 1.30 0.30

4.70 3.20 1.60 0.20

5.70 2.90 4.20 1.30

5.50 2.40 3.70 1.00

6.40 2.80 5.60 2.20

6.30 2.80 5.10 1.50

0.00 0.00 0.00 0.00

主题 7: 6.20 2.90 4.30 1.30

6.50 3.00 5.80 2.20

7.70 2.80 6.70 2.00

4.30 3.00 1.10 0.10

5.80 2.70 5.10 1.90

6.30 2.50 4.90 1.50

5.10 3.80 1.50 0.30

4.40 2.90 1.40 0.20

6.70 2.50 5.80 1.80

主题 10: 5.80 4.00 1.20 0.20

4.60 3.20 1.40 0.20

7.00 3.20 4.70 1.40

6.20 3.40 5.40 2.30

6.60 3.00 4.40 1.40

5.90 3.00 4.20 1.50

6.70 3.10 4.70 1.50

5.00 3.20 1.20 0.20

5.70 2.60 3.50 1.00

主题 12: 6.70 3.10 4.40 1.40

5.40 3.70 1.50 0.20

6.30 2.30 4.40 1.30

6.50 2.80 4.60 1.50

5.00 2.00 3.50 1.00

6.50 3.20 5.10 2.00

7.60 3.00 6.60 2.10

6.40 3.20 4.50 1.50

4.60 3.10 1.50 0.20

这是 CSV 文件

c multithreading csv concurrency pthreads
1个回答
0
投票

您遇到一些打印问题,因为正如您所说,某些线程与打印重叠,所有线程都同时打印,因此您的输入完全正常。

如果你想避免这种情况,你可以使用互斥锁,在打印之前锁定它,并在“打印之后解锁它” " 打印或者您可以使用 snprintf 一次打印所有行

使用示例:

#include <stdio.h>

int main() {
    int number = 123;
    char character = 'A';
    char *string = "Hello";

    char buffer[100]; // Make sure the buffer can contain all the character

    sprintf(buffer, "Number: %d, Character: %c, String: %s", number, character, string);

    printf("Formatted String: %s\n", buffer);

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.