3

Pythonのパイプメソッドの勉強を始めたばかりです。パイプ記述子をファイルオブジェクトにラップして、行ごとに読み取ろうとしました。

import os,time,threading

def child():
    while True:
        time.sleep(1)
        msg = ('Spam\n' ).encode()
        os.write(pipeout,msg)


def parent(): 
    while True:
        a = os.fdopen(pipein)
        line = a.readline()[:-1]
        print('Parent %d got [%s] at %s' % (os.getpid(),line,time.time()))

pipein,pipeout = os.pipe()

threading.Thread(target=child,args=()).start()

parent()

スクリプトを実行すると、結果は次のようになります----スクリプトは最初の反復で機能し、エラーメッセージが表示されます

Parent 621 got [Spam] at 1376785841.4  
Traceback (most recent call last):
  File "/Users/miteji/pipe-thread.py", line 43, in <module>
    parent()
  File "/Users/miteji/pipe-thread.py", line 36, in parent
    line = a.readline()[:-1]
IOError: [Errno 9] Bad file descriptor
>>> Exception in thread Thread-1:
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py",         line 551, in __bootstrap_inner
     self.run()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 504, in run
     self.__target(*self.__args, **self.__kwargs)
  File "/Users/miteji/pipe-thread.py", line 30, in child
     os.write(pipeout,msg)
OSError: [Errno 32] Broken pipe

でも、着替えたら

a = os.fdopen(pipein)
line = a.readline()[:-1]

line = os.read(pipein,32)

スクリプトは正常に動作します。

では、なぜ「os.fdopen」メソッドを使用できないのでしょうか? なぜパイプが壊れたのですか?皆さん、ありがとうございました!

4

1 に答える 1

1

os.fdopen問題は、ここの配置にあります。

def parent(): 
    while True:
        a = os.fdopen(pipein)
        line = a.readline()[:-1]
        print('Parent %d got [%s] at %s' % (os.getpid(),line,time.time()))

ループを通過するたびに、以前に行った場合でも、os.fdopen() 再度を呼び出します。

初めて実行するときは、以前は実行していなかったos.fdopen()ので、すべて問題ありません。aしかし、2 回目は、以前の値を破棄して、新しい結果に再バインドしos.fdopen()ます。

以前の値が破棄されると、ガベージ コレクションの対象になります。CPython は (参照カウントのため) すぐに気づき、それを収集します。これにより、 を呼び出す基になるオブジェクトが削除されますos.fdclose()。これにより、パイプが閉じます。

当面の問題を解決するには、ループの外でパイプを 1 回だけ開くようにしてください。

于 2013-08-18T01:11:08.273 に答える