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

标签 python linux subprocess

我注意到在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)遵循 stdinstdout 管道的创建,以便写入管道端不会被 p2 继承并被 有效关闭p1.stdin.close().

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

相关文章:

python - 如何计算 DataFrame 对象中的类别数?

python - arr.__len__() 是在 Python 中获取数组长度的首选方法吗?

python - Colab 以 ^C 结束

python - subprocess.popen() 的实时输出而不是逐行输出

Python 并行子进程命令同时抑制输出

python - 在 django vanilla CreateView 上设置当前用户

c++ - 数据结构对齐

linux - “glSwapInterval”未在此范围内声明

linux - tar 从存档内的文件夹中提取所有文件

python - 如何对使用 Popen 的函数进行单元测试?