无法在Python中打开线程创建的管道描述符

无法在Python中打开线程创建的管道描述符,python,multithreading,pipe,Python,Multithreading,Pipe,我刚开始研究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)

我刚开始研究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

这些纸条很好用


那么为什么不能使用“os.fdopen”方法呢?为什么管子断了?谢谢大家!

问题在于
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
重新绑定到新结果,放弃了先前的
os.fdopen()

当放弃较早的值时,它就有资格进行垃圾收集。CPython立即通知(由于参考计数)并收集。这将删除底层对象,该对象调用
os.fdclose()
。这反过来又关闭了管道

要解决眼前的问题,请确保只在循环外部打开管道一次

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