我刚开始研究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”方法呢?为什么管子坏了?谢谢大家!
答案 0 :(得分: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
重新绑定到新结果,放弃之前的os.fdopen()
值。
当放弃早期值时,它就有资格进行垃圾回收。 CPython立即通知(由于引用计数)并收集它。这将删除调用os.fdclose()
的基础对象。反过来,这会关闭管道。
要解决当前问题,请确保只在循环外打开一次管道。