redirección io para "cruzar" 2 programas

redirección io para "cruzar" 2 programas

¿Cómo "cruzar" stdiny stdoutde dos programas? Específicamente, tengo 2 programas llamados pgm1y pgm2, son juegos interactivos de tres en raya. Ambos generan un número (0to8) que indica la posición donde quiere marcar y esperan otro número (0to8) que indica dónde quiere marcar el usuario. La diferencia entre los dos es pgm1que hace el primer movimiento y pgm2hace el segundo movimiento. Ambos funcionan bien a través de un usuario interactivo. ¿Se puede hacer que jueguen entre sí mediante la redirección io?

Intenté las siguientes cosas en vano:

  1. Ábralo pgm2en una terminal separada (espera entrada), busque su pid. Luego ejecuta pgm1en otra terminal ./pgm1 < /proc/pid_pgm2/fd/1 > /proc/pid_pgm2/fd/0
  2. Hice 2 tuberías usando mkfifo, digamos pipe1y pipe2ejecuté lo siguiente en dos terminales diferentes: ./pgm1 < pipe1 > pipe2y./pgm2 < pipe2 > pipe1
  3. Probé los dos anteriores, ejecutando pgm1 antes de pgm2, ejecutando pgm2 antes de pgm1.
    Me aseguré de usarlo fflush(stdout)en ambos programas, inmediatamente después de usar printf().

¿Alguien podría decirme qué me falta o qué me sale mal o es posible?

Respuesta1

Debería poder hacer que esto funcione con un FIFO y una tubería.

$ mkfifo fifo
$ ./pgm2 < fifo | ./pgm1 > fifo

La entrada del programa dos es el quince y las salidas a la tubería. La entrada del programa uno es la tubería y las salidas al FIFO.

Sin embargo, tenga cuidado: esto es muy picante en general y puede bloquearse si el "ping/pong" entre los procesos no es perfecto.

Vea también esta pregunta de Stack Overflow:¿Cómo redirigir la salida estándar del segundo proceso a la entrada estándar del primer proceso?

Respuesta2

Tienes un punto muerto en tu: ./pgm1 < pipe1 > pipe2y./pgm2 < pipe2 > pipe1

Lo open("pipe1", O_RDONLY)realizado por el shell antes de la ejecución pgm1se bloqueará hasta que algo más escriba openen esa misma tubería. Hasta que no se haga, no funcionará el siguiente open("pipe2", O_WRONLY).

Lo mismo para el otro. Se open("pipe2", O_RDONLY)bloqueará y debido a que open("pipe2", O_WRONLY)no se realizará porque el otro shell está esperando un escritor pipe1, tienes un punto muerto.

¿Lo habías escrito?

pgm1 < pipe1 > pipe2 & pgm2 > pipe1 < pipe2

Habría funcionado.

En Linux, también puedes escribirlo:

{ pgm1 <&3 3<&- | pgm2 3<&-; } 3< /dev/fd/1 | :

información relacionada