![io-Umleitung zum "Kreuzen" von 2 Programmen](https://rvso.com/image/50583/io-Umleitung%20zum%20%22Kreuzen%22%20von%202%20Programmen.png)
stdin
Wie kann man und stdout
zwei Programme „kreuzen“ ? Genauer gesagt habe ich zwei Programme, die pgm1
und aufrufen pgm2
, es sind interaktive Tic-Tac-Toe-Spiele. Beide geben eine Zahl (0 bis 8) aus, die die Position angibt, die markiert werden soll, und erwarten eine weitere Zahl (0 bis 8), die angibt, wo der Benutzer markieren möchte. Der Unterschied zwischen den beiden besteht darin, dass der pgm1
erste Zug und pgm2
der zweite Zug ausgeführt werden. Beide funktionieren über den interaktiven Benutzer einwandfrei. Kann man sie mithilfe der E/A-Umleitung gegeneinander spielen lassen?
Folgende Dinge habe ich vergeblich versucht:
- Öffnen Sie es
pgm2
in einem separaten Terminal (es wartet auf Eingabe), suchen Sie seine PID. Führen Sie es dannpgm1
in einem anderen Terminal aus./pgm1 < /proc/pid_pgm2/fd/1 > /proc/pid_pgm2/fd/0
- Habe 2 Pipes mit mkfifo erstellt, sagen wir
pipe1
undpipe2
und habe Folgendes in zwei verschiedenen Terminals ausgeführt:./pgm1 < pipe1 > pipe2
und./pgm2 < pipe2 > pipe1
- habe die beiden oben genannten ausprobiert, indem ich pgm1 vor pgm2 ausgeführt habe, wobei ich pgm2 vor pgm1 ausgeführt habe.
Ich habe darauf geachtet, esfflush(stdout)
in beiden Programmen unmittelbar nach der Verwendung zu verwendenprintf()
.
Kann mir jemand sagen, was ich übersehe / oder falsch mache / oder ist das überhaupt möglich?
Antwort1
Mit einem FIFO und einer Pipe sollte es möglich sein, dies zum Laufen zu bringen.
$ mkfifo fifo
$ ./pgm2 < fifo | ./pgm1 > fifo
Der Eingang von Programm zwei ist der FIFO und die Ausgänge erfolgen an die Pipe. Der Eingang von Programm eins ist die Pipe und die Ausgänge erfolgen an den FIFO.
Aber Vorsicht: Dies ist im Allgemeinen sehr riskant und kann zu einem Deadlock führen, wenn das „Ping/Pong“ zwischen den Prozessen nicht perfekt ist.
Siehe auch diese Stack Overflow-Frage:Wie leite ich die Standardausgabe des 2. Prozesses zurück zur Standardeingabe des 1. Prozesses um?
Antwort2
Sie haben einen Deadlock in Ihrem: ./pgm1 < pipe1 > pipe2
und./pgm2 < pipe2 > pipe1
Die open("pipe1", O_RDONLY)
von der Shell vor der Ausführung ausgeführten Aktionen werden blockiert, bis etwas anderes in dieselbe Pipe pgm1
schreibt . Bis dies erledigt ist, wird das nächste nicht ausgeführt .open
open("pipe2", O_WRONLY)
Dasselbe gilt für das andere. Das open("pipe2", O_RDONLY)
wird blockiert und da das open("pipe2", O_WRONLY)
nicht ausgeführt wird, da die andere Shell auf einen Writer wartet pipe1
, haben Sie einen Deadlock.
Hättest du es geschrieben
pgm1 < pipe1 > pipe2 & pgm2 > pipe1 < pipe2
Es hätte funktioniert.
Unter Linux können Sie es auch schreiben:
{ pgm1 <&3 3<&- | pgm2 3<&-; } 3< /dev/fd/1 | :