我注意到在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
程序在 Python2 上挂起,在 Python3 上不会挂起,并且如果 close_fds
设置为 True
则根本不会挂起。所以我想知道......那里的实际问题是什么?
编辑:它卡在我的 Python 2.6 上,并停止卡在 2.7 上
最佳答案
What was the actual issue there?
在 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()
.
关于python - 为什么在 Python 2 中 close_fds=False 有时会挂起进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55726732/