【问题标题】:Why close_fds=False sometimes hangs the process in Python 2?为什么 close_fds=False 有时会在 Python 2 中挂起进程?
【发布时间】:2019-04-17 11:38:58
【问题描述】:

我注意到在 Python3 子进程中,Popen 参数 close_fds 的默认值从 False 更改为 True,我想知道 原因 是什么以及 是否是一个好习惯strong>几乎总是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 设置为True,程序会在Python2 上挂起,在Python3 上不会挂起并且根本不会挂起。所以我想知道......那里的实际问题是什么?

编辑:它挂在我的 Python 2.6 上并停止挂在 2.7 上

【问题讨论】:

    标签: python linux subprocess


    【解决方案1】:

    那里的实际问题是什么?

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

    在 Python 2.7 中,fcntl(…, F_SETFD, FD_CLOEXEC) 的调用遵循stdinstdout 管道的创建,因此写入管道末端不会被p2 继承并被p1.stdin.close() 有效关闭。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-17
      • 2018-10-12
      • 2014-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多