FIFOを読む前に、なぜプロセスが存在しないのでしょうか?

FIFOを読む前に、なぜプロセスが存在しないのでしょうか?

単純なPythonスクリプトがあります。

#!/usr/bin/python

import os, sys

sys.stderr.write('I am %s' % os.getpid())
sys.stderr.flush()

print "hello"

sys.stderr.write('I am done')

Bashでこのスクリプトを実行し、標準出力をFIFOにリダイレクトすると、次のようになります。

$ mkfifo fifo
$ /pyscript > fifo

奇妙なことは、FIFOを読み取る前に次のようなことです。

  • 「I am (PID)」というメッセージは表示されません。

  • 使用されたスクリプトを表示できません。ps -ef

  • そして使用ラソフ、そんな人はいないと思います。先入選出ファイルオープン!

FIFOを読むとすぐにstderrに書き込んだ2つのメッセージがすぐに表示されます。

何が問題なの?


背景:私はFIFOを生成し、ここに「hello」を書くテストを書いています。その後、テストを実行し、SUTを期待します。いいえIEで読みます。ただファイルを無視してください。私はこれを試しましたが、mkfifo test_fifo; /bin/echo hello > test_fifo &; run_the_test; killall echo驚くべきことに、そのechoプロセスは存在しませんでした!このようなテストの後、どのように「クリーンアップ」(除外)する必要がありますかrm test_fifo

答え1

シェルは、ファイルのリダイレクトが正常に完了するまでプログラムを実行しません。このコマンドはpyscript > fifoシェルをフォークしてから開こうとします。これは、一部のプロセスがすでに読み取り用にfifo開いている場合にのみ成功します。fifoそれまで、サブシェルはパイプライン待機状態にあります。

$ (sleep 10;ps -l -t pts/0)&
[1] 2574
$ pyscript > fifo
F S   UID    PID   PPID WCHAN  TTY    CMD
0 S  1000   2554   2535 wait   pts/0  bash  //interactive shell
1 S  1000   2574   2554 wait   pts/0  bash  //fork of shell, parent of sleep and ps
1 S  1000   2576   2554 pipe_w pts/0  bash  //fork of shell, waiting to open fifo
0 R  1000   2577   2574 -      pts/0  ps

答え2

パイプまたはFIFOの両端を同時に開く必要があります。プロセスが作成されていないパイプまたはFIFOファイルから読み取られた場合(おそらくすべてがファイルが閉じられたか終了したため)、読み取り時にファイルの終わりが返されます。読み取りプロセスなしでパイプまたはFIFOへの書き込みはエラー条件と見なされ、SIGPIPE信号を生成し、信号が処理またはブロックされるとエラーコードEPIPEで失敗します。

http://www.gnu.org/software/libc/manual/html_node/Pipes-and-FIFOs.html

関連情報