![io перенаправление на "перекресток" 2 программ](https://rvso.com/image/50583/io%20%D0%BF%D0%B5%D1%80%D0%B5%D0%BD%D0%B0%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%BD%D0%B0%20%22%D0%BF%D0%B5%D1%80%D0%B5%D0%BA%D1%80%D0%B5%D1%81%D1%82%D0%BE%D0%BA%22%202%20%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC.png)
Как "скрестить" stdin
и stdout
двух программ? В частности, у меня есть 2 программы, которые называют pgm1
и pgm2
, это интерактивные игры в крестики-нолики. Они обе выводят число (от 0 до 8), указывающее позицию, где они хотят отметить, и ожидают другое число (от 0 до 8), указывающее, где пользователь хочет отметить. Разница между ними в том, что pgm1
делает первый ход и pgm2
делает второй ход. Они обе прекрасно работают через интерактивного пользователя. Можно ли заставить их играть друг против друга с помощью перенаправления ввода-вывода?
Я безуспешно пытался сделать следующее:
- Откройте
pgm2
в отдельном терминале (он ждет ввода), найдите его pid. Затем запуститеpgm1
в другом терминале./pgm1 < /proc/pid_pgm2/fd/1 > /proc/pid_pgm2/fd/0
- Сделал 2 канала с помощью mkfifo, скажем,
pipe1
иpipe2
и запустил следующее на двух разных терминалах:./pgm1 < pipe1 > pipe2
и./pgm2 < pipe2 > pipe1
- попробовал два из вышеперечисленных вариантов, запуск pgm1 перед pgm2, запуск pgm2 перед pgm1,
я обязательно использовалfflush(stdout)
в обеих программах, сразу после использованияprintf()
.
Может ли кто-нибудь сказать мне, что я упускаю или делаю не так, или возможно ли это вообще?
решение1
Вы должны суметь заставить это работать с FIFO и каналом.
$ mkfifo fifo
$ ./pgm2 < fifo | ./pgm1 > fifo
Вход программы два — fifo, а выходы в канал. Вход программы один — pipe, а выходы в fifo.
Однако будьте осторожны: в целом это очень динамично и может привести к тупиковой ситуации, если «пинг-понг» между процессами не идеален.
См. также этот вопрос на Stack Overflow:Как перенаправить stdout 2-го процесса обратно в stdin 1-го процесса?
решение2
У вас возник тупик в: ./pgm1 < pipe1 > pipe2
и./pgm2 < pipe2 > pipe1
Выполненное open("pipe1", O_RDONLY)
оболочкой перед выполнением pgm1
будет блокироваться, пока что-то еще не выполнит запись open
в тот же канал. Пока это не будет сделано, он не выполнит следующее open("pipe2", O_WRONLY)
.
То же самое и для другого. open("pipe2", O_RDONLY)
Будет заблокирован и поскольку open("pipe2", O_WRONLY)
не будет выполнен, так как другая оболочка ждет записи на pipe1
, у вас возникнет взаимоблокировка.
Ты это написал?
pgm1 < pipe1 > pipe2 & pgm2 > pipe1 < pipe2
Это бы сработало.
В Linux вы также можете написать это:
{ pgm1 <&3 3<&- | pgm2 3<&-; } 3< /dev/fd/1 | :