io-Umleitung zum "Kreuzen" von 2 Programmen

io-Umleitung zum "Kreuzen" von 2 Programmen

stdinWie kann man und stdoutzwei Programme „kreuzen“ ? Genauer gesagt habe ich zwei Programme, die pgm1und 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 pgm1erste Zug und pgm2der 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:

  1. Öffnen Sie es pgm2in einem separaten Terminal (es wartet auf Eingabe), suchen Sie seine PID. Führen Sie es dann pgm1in einem anderen Terminal aus./pgm1 < /proc/pid_pgm2/fd/1 > /proc/pid_pgm2/fd/0
  2. Habe 2 Pipes mit mkfifo erstellt, sagen wir pipe1und pipe2und habe Folgendes in zwei verschiedenen Terminals ausgeführt: ./pgm1 < pipe1 > pipe2und./pgm2 < pipe2 > pipe1
  3. 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, es fflush(stdout)in beiden Programmen unmittelbar nach der Verwendung zu verwenden printf().

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 > pipe2und./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 pgm1schreibt . Bis dies erledigt ist, wird das nächste nicht ausgeführt .openopen("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 | :

verwandte Informationen