системный вызов read возвращает -1 при чтении из канала в дочернем процессе - PullRequest
2 голосов
/ 10 апреля 2019

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

После этого второй дочерний процесс должен прочитать их, преобразовать их в верхний регистр и записать в другой файл.Системный вызов read во втором дочернем процессе возвращает -1 при чтении из канала.Также, когда я выполняю программу, в некоторых случаях printf у первого потомка ничего не печатает, а в других случаях printf у второго потомка тоже не печатает.Не могли бы вы указать ошибки в программе, которые вызывают проблемы?

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

    int fd[2];

    long length;
    char buff1[250];
    char buff2[250];

    FILE * fptr1;
    FILE * fptr2;

    pid_t A, B;
    pipe(fd);

    A = fork();

    if (A == -1) {
        printf("error in fork of A\n");
        exit(1);
    }
    if (A == 0) {
        fptr1 = fopen(argv[1], "r"); // program receives file names as argument

        if (fptr1 == NULL) {
            printf("Erro in file open1\n");
            exit(1);
        }

        fseek(fptr1, 0 L, SEEK_END);
        length = ftell(fptr1);
        fseek(fptr1, 0 L, SEEK_SET);

        close(fd[0]);

        fread(buff1, length, 1, fptr1);
        buff1[length] = '\0';
        printf("buff1 = %s", buff1);
        write(fd[1], buff1, length);

        fclose(fptr1);
        exit(0);
    } else {
        B = fork();
        if (B == -1) {
            printf("Error in forking child B");
            exit(1);
        }
        if (B == 0) {
            fptr2 = fopen(argv[2], "w");

            if (fptr2 == NULL) {
                printf("Error in file open2\n");
                exit(1);
            }

            close(fd[1]);
            int n = read(fd[0], buff2, length);
            printf("n = %d\n", n);
            upper_string(buff2); // converts characters to uppecase
            fwrite(buff2, 1, length, fptr2);
            fclose(fptr2);
        }
    }
    return 0;
}

1 Ответ

0 голосов
/ 10 апреля 2019

Здесь нужно учесть несколько вещей.Первое, что я хотел бы отметить, это то, что вам не нужно использовать два вызова fork ().В этом случае у вас есть три процесса, работающих параллельно (родительский процесс и два дочерних процесса, по одному на каждый вызов fork ()).

При работе с процессами, работающими параллельно, следует учитывать один важный момент - синхронизм,В вашем коде вы создаете два процесса.Родительский процесс не ждет ни одного из своих дочерних процессов, поэтому он завершает свое выполнение, и если дочерние процессы не завершены, они станут дочерними для процесса init.Но, судя по всему, у вас типичная проблема для потребителя.Один из вашего ребенка производит что-то, а другой потребляет это, но, как они работают параллельно, потребитель должен знать, что продукт готов к употреблению.Итак, в этом случае, я думаю, что самый простой способ выполнить эту работу - это использовать только один fork (), чтобы дочерний процесс становился производителем, а родительский процесс (потребитель) ждал, пока его дочерний процесс завершит работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...