Pythonプログラム用のosである.パイプやos.フォーク()を発行
質問
私は最近執筆し、その内容をスクリプトを実行 os.フォーク() 分割を行う二つのプロセス。の子プロセスがサーバプロセスを通過データを親プロセス用のパイプを作成 os.pipe().の子どもを閉じる 'r'
のパイプの親を閉じる 'w'
のパイプとなります。I変換を返しますからパイプ)のファイルオブジェクト os.fdopen.
の問題なんです:のたフォークの子となります。べての動作の子dutifullyに書き込みデータ、オープン 'w'
のパイプです。残念ながら、親会社のパイプは不思議なもの:
A)でブロックの read()
の操作 'r'
のパイプです。
第二に、読み込みに失敗するとデータのパイプのない限り、 'w'
端が完全に閉じられます。
ってすぐに感じたのはこのバッファリングの問題を追加 パイプです。flush() 通話がなかった。
誰でもできるので明のデータが表示されていないので、書き終了です。やはり戦略の read()
呼び非ブロック?
これは私の初めてのPythonプログラム短期または使用管の場合はご容赦ためのシェイプを作ってみました単純な間違いです。
解決
あなたはサイズを指定する、またはイテレータ(for line in f
)としてパイプを治療せずに読み取りを()を使用していますか?もしそうなら、それはおそらくあなたの問題の原因だ - 読み()だけで読書のために利用可能であるものを読むのではなく、返す前に、ファイルの最後まで読むために定義されています。それは、子供がclose()を呼び出すまで、それをブロックすることを意味します。
にリンクされているサンプルコードでは、これはOKです - 親がブロッキング的に作用し、ちょうど隔離のために子を使用しています。あなたは、その後、継続のどちらかあなたが投稿したコードのようなIOを非ブロックを使用する(ただし、半完全なデータを扱うために準備すること)、または例えばr.read(サイズ)またはr.readline(チャンクで読みたい場合は() )特定のサイズ/行が読み出されるまでにのみブロックされます。 (あなたはまだ子供でフラッシュを呼び出す必要があります)。
あなたはすぐに消費される各ラインが必要な場合は、これは、反復子は「for line in r:
」のためだけでなく、いくつかの更なるバッファを使用しているとのパイプを処理するように見えるが何をしたいあなたを与えることがありません。これを無効にすることは可能かもしれないが、ただのfdopenにバッファサイズに0を指定すると、十分ないないようです。
HERESにいくつかのサンプルコード:
import os, sys, time
r,w=os.pipe()
r,w=os.fdopen(r,'r',0), os.fdopen(w,'w',0)
pid = os.fork()
if pid: # Parent
w.close()
while 1:
data=r.readline()
if not data: break
print "parent read: " + data.strip()
else: # Child
r.close()
for i in range(10):
print >>w, "line %s" % i
w.flush()
time.sleep(1)
他のヒント
使用
fcntl.fcntl(readPipe, fcntl.F_SETFL, os.O_NONBLOCK)
の読み取りを呼び出す前に()の両方の問題を解決しました。読み取り()の呼び出しはもはやブロックしているとのデータが書き終わりにちょうどフラッシュ()の後に表示されてます。
いまこそ、問題解決のブロックi/oバッファリング.
注する場合には、その結果生じるい異なるアプローチ:サブプロセスは、相当/交換のためのフォーク/execム.うことになるださい:いただいたばかりのフォークは、exec)およびデータ交換のプロセス--この場合、 multiprocessing
モジュール(Python2.6+)されます。
Pythonアプリケーションにおけるフォークの「子」の部分対「親」は愚かです。これは、16ビットのUNIX日から遺産です。これは、フォーク/ execのとexecは小さな小さなプロセッサを最大限に活用するための重要事項だった日から気取りだ。
2つの別個の部分にあなたのPythonコードをブレーク:親と子
親部品は、子部品を実行するためにサブプロセスして使用する必要があります。
フォークとexecは、どこかで起こるかもしれません - しかし、あなたは気にする必要はありません。
。