我注意到在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,则根本不挂起。所以我想…那里的实际问题是什么?
编辑:它挂在我的Python2.6上,不再挂在2.7上

最佳答案

那里的实际问题是什么?
在Python2.6中,p1.stdin管道的写端的文件句柄由p2继承,后者不关心或不知道它,因此保持打开状态。因此,尽管父进程确实p1.stdin.close(),但写入管道仍保持打开状态,因此cat不会在其输入上检测到eof,并一直等待来自管道的数据,从而阻塞整个进程链。
在python 2.7中,fcntl(…, F_SETFD, FD_CLOEXEC)的调用遵循stdinstdout管道的创建,这样写管道端就不会被p2继承,也不会被p1.stdin.close()有效地关闭。

关于python - 为什么close_fds = False有时会在Python 2中挂起进程?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55726732/

10-12 21:50