Раздвоенный ребенок "печатает" перенаправленный stdout дважды - PullRequest
0 голосов
/ 12 мая 2019

Через некоторое время (1) я пытаюсь:

  • порождать дочерний процесс с помощью fork ();

  • перенаправитьСтандартный процесс дочернего процесса, чтобы родительский процесс мог его видеть

  • распечатать результат в терминале из родительского процесса

  • повтор

Странно, но вывод дочернего процесса печатается дважды

// parentToChild  and  childToParent are the pipes I'm using

while(1) {

int pid = fork();
    if(pid < 0) {
    // error, get out
    exit(0);
} else if(pid != 0) {
    // parent process
    close(parentToChild[0]); // don't need read end of parentToChild
    close(childToParent[1]); // don't need write end of childToParent

    sleep(4);
    char respBuffer[400];
    int respBufferLength = read(childToParent[0], respBuffer, sizeof(respBuffer));
    printf("before\n");
    printf("parent tried to read something from its child and got: %s\n", respBuffer);
    printf("after\n");
} else if (pid == 0) {
    if(dup2(childToParent[1], STDOUT_FILENO) < 0) {
        // printf("dup2 error");
    };
    close(childToParent[1]);       
    close(childToParent[0]);

    close(parentToChild[1]);    // write end of parentToChild not used

    printf("child message");

    // if we don't exit here, we run the risk of repeatedly creating more processes in a loop
    exit(0);
}
}

Я ожидаю, что выход следующего цикла на каждой итерации будет:

before
parent tried to read something from its child and got: child message
after

Но вместо этого на каждой итерации я получаю:

before
parent tried to read something from its child and got: child message
after
child message

В чем причина второй печати "дочернего сообщения"?

Очистка буферов stdout перед вызовом fork ()Кажется, проблема не решается

Интересно, что удаление цикла while и сохранение всего остального в исправном состоянии работает нормально

1 Ответ

1 голос
/ 12 мая 2019

В первой итерации цикла вы закрываете childToParent[1] в родительском элементе и не воссоздаете каналы, поэтому во второй итерации цикла он пытается повторно использовать эти закрытые каналы, поэтому дочерний элемент dup2 вызов не удался, поэтому его printf отправляется на терминал.Между тем, в родительском элементе вызов read возвращает 0, ничего не записывая в буфер, поэтому вы просто печатаете старое содержимое.

...