io перенаправление на "перекресток" 2 программ

io перенаправление на "перекресток" 2 программ

Как "скрестить" stdinи stdoutдвух программ? В частности, у меня есть 2 программы, которые называют pgm1и pgm2, это интерактивные игры в крестики-нолики. Они обе выводят число (от 0 до 8), указывающее позицию, где они хотят отметить, и ожидают другое число (от 0 до 8), указывающее, где пользователь хочет отметить. Разница между ними в том, что pgm1делает первый ход и pgm2делает второй ход. Они обе прекрасно работают через интерактивного пользователя. Можно ли заставить их играть друг против друга с помощью перенаправления ввода-вывода?

Я безуспешно пытался сделать следующее:

  1. Откройте pgm2в отдельном терминале (он ждет ввода), найдите его pid. Затем запустите pgm1в другом терминале ./pgm1 < /proc/pid_pgm2/fd/1 > /proc/pid_pgm2/fd/0
  2. Сделал 2 канала с помощью mkfifo, скажем, pipe1и pipe2и запустил следующее на двух разных терминалах: ./pgm1 < pipe1 > pipe2и./pgm2 < pipe2 > pipe1
  3. попробовал два из вышеперечисленных вариантов, запуск 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 | :

Связанный контент