![2 つのプログラムを「横断」する io リダイレクト](https://rvso.com/image/50583/2%20%E3%81%A4%E3%81%AE%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%82%92%E3%80%8C%E6%A8%AA%E6%96%AD%E3%80%8D%E3%81%99%E3%82%8B%20io%20%E3%83%AA%E3%83%80%E3%82%A4%E3%83%AC%E3%82%AF%E3%83%88.png)
stdin
2 つのプログラムのとを「交差」させるにはどうすればよいですかstdout
? 具体的には、 と という 2 つのプログラムがありpgm1
、pgm2
これらは対話型の三目並べゲームです。 どちらもマークする位置を示す数値 (0 ~ 8) を出力し、ユーザーがマークする位置を示す別の数値 (0 ~ 8) を期待します。 2 つの違いは、 がpgm1
最初の動きを行い、 がpgm2
2 番目の動きを行うことです。 どちらも対話型ユーザー経由では正常に動作します。 io リダイレクトを使用して、これらを互いに対戦させることができますか?
以下のことを試してみましたが、うまくいきませんでした。
- 別のターミナルで開き
pgm2
(入力を待ちます)、そのPIDを見つけます。次にpgm1
別のターミナルで 実行します。./pgm1 < /proc/pid_pgm2/fd/1 > /proc/pid_pgm2/fd/0
- mkfifo を使用して 2 つのパイプを作成し、 と と入力して
pipe1
、pipe2
2 つの異なるターミナルで以下を実行しました./pgm1 < pipe1 > pipe2
。./pgm2 < pipe2 > pipe1
- 上記の 2 つを試しました。pgm1 を pgm2 の前に実行し、pgm2 を pgm1 の前に実行しました。両方のプログラムで、 を使用した直後に
を使用していることを確認しました。fflush(stdout)
printf()
何が足りないのか、何が間違っているのか、あるいはこれが可能なのか、誰か教えてもらえますか?
答え1
FIFO とパイプを使用すれば、これを動作させることができるはずです。
$ mkfifo fifo
$ ./pgm2 < fifo | ./pgm1 > fifo
プログラム 2 の入力は FIFO で、出力はパイプに送られます。プログラム 1 の入力はパイプで、出力は FIFO に送られます。
ただし、注意してください: これは一般に非常に競合が多く、プロセス間の「ping/pong」が完璧でない場合はデッドロックが発生する可能性があります。
この Stack Overflow の質問も参照してください:2 番目のプロセスの stdout を 1 番目のプロセスの stdin にリダイレクトするにはどうすればよいですか?
答え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 | :