为什么close_fds = False有时会挂起Python 2中的进程?

问题描述 投票:1回答:1

我注意到在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上

python linux subprocess
1个回答
2
投票

那里的实际问题是什么?

在Python 2.6中,p1.stdin管道写入端的文件句柄由p2继承,它不关心或不了解它,因此保持打开状态。因此,虽然父进程执行p1.stdin.close(),但写入管道保持打开,因此cat不会在其输入上检测到EOF并继续等待来自管道的数据,从而阻塞整个流程链。

使用fcntl(…, F_SETFD, FD_CLOEXEC)的Python 2.7调用跟随stdinstdout管道的创建,因此写管道端不会被p2继承并且被p1.stdin.close()有效关闭。

© www.soinside.com 2019 - 2024. All rights reserved.