Предотвращение тупиков, порядок выполнения случайных потоков C - PullRequest
0 голосов
/ 13 октября 2019

Я строю программу для школьного задания. Он имеет следующие требования, как показано ниже.

  • Необходимо использовать мьютексы

  • Необходимо использовать Pthreads

  • Создайте 5 потоков со случайной синхронизацией (иначе говоря, работающие в неконкретном порядке)

  • Потоки должны быть отсоединены от основного потока

  • Каждый поток будет читать из файла и корректировать баланс банковского счета, каждый с различными входными файлами.

Это ссылка на фактическое назначение и то, что мы должны бытьделаю это для чуть более детального набора информации AssignmentTxtFile

Мой главный вопрос - решить проблему взаимоблокировки, с которой я столкнулся. Я не знаю, как именно подойти к этой проблеме, я понимаю, что мне нужно найти способ, чтобы он не входил в критические разделы нескольких потоков в любой момент времени. Как я собираюсь сделать это, сохраняя порядок выполнения случайным образом?

Вот код, который у меня сейчас есть для этой программы.

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





pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;


float balance = 0;



void *thread1(void *value){

    FILE *fPTR;
    char buffer;
    float number;

    char *fileName = "data1.in";

    fPTR = fopen(fileName, "r");

    if (fPTR == NULL){

        printf("was unable to open: %s\n", fileName);
        return NULL;
    }

    while(1){



        //Critical Section of Thread1
        pthread_mutex_lock(&mutex1);
            fscanf(fPTR, "%c%f\n", &buffer, &number);

            if(buffer == '+'){

                balance += number;

            }
            if(buffer == '-'){

                balance -= number;
            }


            printf("Account balance of thread1 is: %f\n", balance);

            if(feof(fPTR)){

                fclose(fPTR);
                printf("end of data1.in");
                return NULL;
            }

            printf("end of while thread1\n");
        pthread_mutex_unlock(&mutex1);

        sleep(.3);
    }


}

void *thread2(void *value){

    FILE *fPTR;
    char buffer;
    float number;

    char *fileName = "data2.in";

    fPTR = fopen(fileName, "r");

    if (fPTR == NULL){

        printf("was unable to open: %s\n", fileName);
        return NULL;
    }

    while(1){



        //Critical Section of Thread2
        pthread_mutex_lock(&mutex1);
            fscanf(fPTR, "%c%f\n", &buffer, &number);

            if(buffer == '+'){

                balance += number;

            }
            if(buffer == '-'){

                balance -= number;
            }


            printf("Account balance of thread2 is: %f\n", balance);

            if(feof(fPTR)){

                fclose(fPTR);
                printf("end of data2.in");
                return NULL;
            }

            printf("end of while thread2\n");
        pthread_mutex_unlock(&mutex1);

        sleep(.3);
    }


}

void *thread3(void *value){

    FILE *fPTR;
    char buffer;
    float number;

    char *fileName = "data3.in";

    fPTR = fopen(fileName, "r");

    if (fPTR == NULL){

        printf("was unable to open: %s\n", fileName);
        return NULL;
    }

    while(1){



        //Critical Section of Thread3
        pthread_mutex_lock(&mutex1);
            fscanf(fPTR, "%c%f\n", &buffer, &number);

            if(buffer == '+'){

                balance += number;

            }
            if(buffer == '-'){

                balance -= number;
            }


            printf("Account balance of thread3 is: %f\n", balance);

            if(feof(fPTR)){

                fclose(fPTR);
                printf("end of data3.in");
                return NULL;
            }

            printf("end of while thread3\n");
        pthread_mutex_unlock(&mutex1);

        sleep(.3);
    }


}

void *thread4(void *value){

    FILE *fPTR;
    char buffer;
    float number;

    char *fileName = "data4.in";

    fPTR = fopen(fileName, "r");

    if (fPTR == NULL){

        printf("was unable to open: %s\n", fileName);
        return NULL;
    }

    while(1){



        //Critical Section of Thread4
        pthread_mutex_lock(&mutex1);
            fscanf(fPTR, "%c%f\n", &buffer, &number);

            if(buffer == '+'){

                balance += number;

            }
            if(buffer == '-'){

                balance -= number;
            }


            printf("Account balance of thread4 is: %f\n", balance);

            if(feof(fPTR)){

                fclose(fPTR);
                printf("end of data4.in");
                return NULL;
            }

            printf("end of while thread4\n");
        pthread_mutex_unlock(&mutex1);

        sleep(.3);
    }


}

void *thread5(void *value){

    FILE *fPTR;
    char buffer;
    float number;

    char *fileName = "data5.in";

    fPTR = fopen(fileName, "r");

    if (fPTR == NULL){

        printf("was unable to open: %s\n", fileName);
        return NULL;
    }

    while(1){



        //Critical Section of Thread5
        pthread_mutex_lock(&mutex1);
            fscanf(fPTR, "%c%f\n", &buffer, &number);

            if(buffer == '+'){

                balance += number;

            }
            if(buffer == '-'){

                balance -= number;
            }


            printf("Account balance of thread5 is: %f\n", balance);

            if(feof(fPTR)){

                fclose(fPTR);
                printf("end of data5.in");
                return NULL;
            }


            printf("end of while thread5\n");
        pthread_mutex_unlock(&mutex1);

        sleep(.3);
    }


}




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



    pthread_t pthread1;
    pthread_t pthread2;
    pthread_t pthread3;
    pthread_t pthread4;
    pthread_t pthread5;



    pthread_create(&pthread1, NULL, thread1, NULL);
    pthread_create(&pthread2, NULL, thread2, NULL);
    pthread_create(&pthread3, NULL, thread3, NULL);
    pthread_create(&pthread4, NULL, thread4, NULL);
    pthread_create(&pthread5, NULL, thread5, NULL);


    pthread_detach(pthread1);
    pthread_detach(pthread2);
    pthread_detach(pthread3);
    pthread_detach(pthread4);
    pthread_detach(pthread5);

    printf("main completed\n");

    pthread_exit(0);



}

1 Ответ

1 голос
/ 13 октября 2019

Простым ответом на этот вопрос относительно того, почему он зашел в тупик или никогда не входил в критические секции, была позиция проверки конца файла, их нужно было вынести за пределы критической секции и внутри циклов while.

Это привело к тому, что потоки никогда не заканчивали из-за того, что им никогда не удавалось разблокировать мьютекс, а затем они вообще не могли войти в критическую секцию.

...