Я пытаюсь настроить двусторонний канал между родительским и дочерним процессами в C, но мой код (как показано ниже) не работает:
int main() {
int fd1[2], fd2[2];
char c;
fprintf(stderr, "Pipe 1 return: %i\n", pipe(fd1));
fprintf(stderr, "Pipe 2 return: %i\n", pipe(fd2));
pid_t pid = fork();
if (pid == -1) {
fprintf(stderr, "Error forking");
return -1;
}
if (!pid) {
dup2(fd1[1], 1);
dup2(fd2[0], 0);
close(fd1[0]);
close(fd2[1]);
//fprintf(stderr, "setvbuffer output: %i\n", setvbuf(stdin, NULL, _IONBF, 0));
fprintf(stderr, "Parent runing. Receiving\n");
c = getchar();
fprintf(stderr, "Parent received char. Modifying\n");
putchar(c + 2);
fprintf(stderr, "Parent sent char\n");
} else {
dup2(fd1[0], 0);
dup2(fd2[1], 1);
close(fd1[1]);
close(fd2[0]);
//fprintf(stderr, "setvbuffer output: %i\n", setvbuf(stdin, NULL, _IONBF, 0));
fprintf(stderr, "Child running. Printing\n");
putchar('c');
c = getchar();
fprintf(stderr, "Child received returned char: %c\n", c);
}
}
Когда я запускаю это, программа сразу же остается в ожидании первого getchar (). Я также пробовал отправлять / получать строки текста, используя закомментированные строки setvbuf (), используя sleep () перед чтением из stdin и т. д.
Это упрощенная версия моего реального кода, который обменивается данными между двумя разными программами, и там я, кажется, могу успешно общаться в одном направлении.
Для ясности и точности не бывает двухходовой трубы. Трубы по своей природе однонаправлены. Но вы можете добиться двунаправленной связи через каналы, используя отдельный канал для каждого направления, и это действительно похоже на то, что вы пытаетесь сделать.
Что касается вашей реальной проблемы, альтернативой отключению буферизации будет fflush() ваших выходных потоков после записи в них.
Также обратите внимание, что после двух dup2 у вас есть 4 открытых файловых дескриптора, которые нужно закрыть.





Как предложил Джон в комментариях, вызов fflush (stdout) после каждого оператора печати устраняет проблему.
Stdio по умолчанию буферизует вывод в каналы. Используйте
setbuf(), чтобы отключить буферизацию.