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

时间:2019-04-17 11:38:58

标签: python linux subprocess

我注意到在Python3子进程中,Popen参数<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <label for="fileInput" class="custom-file-upload" >Choose file</label> <input id="fileInput" name="fileInput" type="file" /> <span class="fileuploadspan">No file selected</span>的默认值已从close_fds更改为False,我想知道原因是什么,以及它是否几乎总是True设置为close_fds(因为我仍在使用Python 2.7)是一种好习惯。

我找到了一个链接,显示了True的问题。

https://bugs.python.org/issue7213

不幸的是,我不清楚为什么会这样。

close_fds=False

如果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,则该程序在Python2上挂起,而在Python3上挂起,并且根本不挂起。所以我想知道...那里的实际问题是什么?

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

1 个答案:

答案 0 :(得分:2)

  

那里的实际问题是什么?

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

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