我注意到在Python3子进程中,Popen参数的默认值close_fds
已从更改False
为True
,我想知道是什么原因,以及几乎始终设置close_fds
为True
(因为我仍在使用Python 2.7)这是一个好习惯。
我发现了一个链接,显示与有关的问题close_fds=False
。
https://bugs.python.org/issue7213
不幸的是,我不清楚为什么会这样。
import subprocess as sub
p1 = sub.Popen(['cat'], stdin=sub.PIPE, stdout=sub.PIPE, close_fds=False)
p2 = sub.Popen(['grep', 'a'], stdin=p1.stdout, stdout=sub.PIPE, close_fds=False)
p1.stdin.write("aaaaaaaaaaaaaaaa\n")
p1.stdin.close()
p2.stdout.read() # Hangs on Python 2
如果close_fds
设置为,程序将在Python2上挂起,而在Python3上不会挂起,也不会挂起True
。所以我想知道……实际的问题是什么?
编辑:它挂在我的Python 2.6上并停止挂在2.7
那里的实际问题是什么?
在Python 2.6中,p1.stdin
管道的写入端的文件句柄由继承p2
,它并不关心或知道它,因此将其保持打开状态。因此,尽管父进程确实这样做了p1.stdin.close()
,但写管道仍保持打开状态,因此写管道cat
不会在其输入上检测到EOF,并一直等待管道中的数据,从而阻塞了整个流程链。
在Python 2.7中,调用和会fcntl(…, F_SETFD, FD_CLOEXEC)
跟随创建stdin
和stdout
管道,从而使写入管道末端不会被继承,也不会p2
有效地被关闭p1.stdin.close()
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句