Дочерний процесс читает данные, прежде чем данные будут записаны в канал с использованием родительского процесса. - PullRequest
1 голос
/ 11 мая 2019

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

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#define INPUT 5

int main() {
    int     fd[2];
    pid_t   childprocess;

    if((childprocess = fork()) < 0) {
        perror("Cannot fork child");
    }

    if(childprocess > 0) {
        // Parent
        int userInput[INPUT];

        close(fd[0]);

        for(int i = 0; i < INPUT; i++) {
            printf("Enter number %d: ", i+1);
            scanf("%d", &userInput[i]);
        }

        write(fd[1], userInput, sizeof(userInput) + 1);

    } else {
        // Child
        close(fd[1]);

        int parentData[INPUT];

        read(fd[0], parentData, sizeof(parentData));

        for(int i = 0; i < INPUT; i++) {
            printf("%d => %d", i+1, parentData[i]);
        }
    }

    return 0;
}

Когда я запускаю программу с помощью ./a.out, я наблюдаю следующее поведение.

Enter number 1: 1 => -4731629522 => 327663 => 2005319684 => 15 => 1

Есть ли какая-либо ошибка в реализации канала, которая вызывает такое поведение?

1 Ответ

3 голосов
/ 11 мая 2019

Проблема в том, что файловые дескрипторы не инициализируются функцией pipe. Когда функция чтения достигнута, fd[0], вероятно, является неверным дескриптором файла. 0 байтов читаются, целые числа, которые записываются в стандартный вывод - это то, что было в неинициализированном массиве parentData. Просто добавьте:

pipe(fd);

Как работает синхронизация? Когда функция read вызывается с допустимым файловым дескриптором, ядро ​​останавливает / блокирует процесс и ожидает, пока другой процесс не записывает запрошенное количество байтов (sizeof parentData) в канал. Затем ядро ​​копирует байты из канала. Это называется блокировкой ввода-вывода.

Примечание: когда процесс записи останавливает / закрывает файловый дескриптор до достижения запрошенного количества байтов, не все байты записываются в буфер. Возвращаемое значение read - это количество прочитанных байтов.

Существует также неблокирующий ввод-вывод. Процесс может делать другие вещи в ожидании данных. Это часто реализуется с помощью потока, который читает (с блокировкой ввода-вывода) из файлового дескриптора / сокета (сетевой ввод-вывод) и устанавливает флаг по окончании.

...