为什么communication()完 成后子进程仍继续运行?

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

我有一个较旧的python 2.7.5脚本,它突然在Red Hat Enterprise Linux Server 7.6(Maipo)上出现问题。毕竟,它在Red Hat Enterprise Linux Server 7.4版(Maipo)上运行良好。该脚本基本上实现了类似于

cat /proc/cpuinfo | grep -m 1 -i 'cpu MHz'

通过创建两个子过程并将第一个子过程的输出传递给第二个子过程(请参见下面的代码示例)。在较新的OS版本上,cat进程保持打开状态,直到脚本终止。

看来,grep管道以某种方式使cat进程保持打开状态,而我找不到任何有关如何显式关闭它的文档。

可以通过将此代码粘贴到python CLI中,然后检查ps进程列表中的静态进程'cat / proc / cpuinfo'来重现该问题。该代码破坏了循环中最初发生的事情,因此请不要争论其样式。 ;-)

import shlex
from subprocess import *
cmd1 = "cat /proc/cpuinfo"
cmd2 = "grep -m 1 -i 'cpu MHz'"
args1 = shlex.split(cmd1) # split into args
args2 = shlex.split(cmd2) # split into args
# first process uses default stdin
ps1 = Popen(args1, stdout=PIPE)
# then use the output of the previous process as stdin
ps2 = Popen(args2, stdin=ps1.stdout, stdout=PIPE)
out, err = ps2.communicate()
print(out)

然后在第二个会话中检查进程列表(!),带有:

ps -eF |grep -v grep|grep /proc/cpuinfo

在RHEL7.4上,进程列表中没有打开的进程,而在RHEL 7.6上经过一些尝试后,它看起来像这样:

[reinski@myhost ~]$ ps -eF |grep -v grep|grep /proc/cpuinfo
reinski    2422  89459  0 26993   356 142 18:46 pts/3    00:00:00 cat /proc/cpuinfo
reinski    2597 139605  0 26993   352  31 18:39 pts/3    00:00:00 cat /proc/cpuinfo
reinski    7809 139605  0 26993   352  86 18:03 pts/3    00:00:00 cat /proc/cpuinfo

这些进程仅在我关闭python CLI时才会消失,在这种情况下,我会收到这样的错误(我将格式原样弄乱了):

cat: write error: Broken pipe
cat: write errorcat: write error: Broken pipe
: Broken pipe

为什么猫显然应该仍然要写入管道,即使它应该已经输出了整个/ proc / cpuinfo并且应该已经终止了它自己?

或更重要的是:如何防止这种情况发生?

感谢您的帮助!

示例2:

根据VPfB的建议,事实证明,我的示例不太幸运,因为可以通过单个grep命令实现预期的结果。因此,这是一个修改后的示例,以另一种方式显示管道问题:

import shlex
from subprocess import *
cmd1 = "grep -m 1 -i 'cpu MHz' /proc/cpuinfo"
cmd2 = "awk '{print $4}'"
args1 = shlex.split(cmd1) # split into args
args2 = shlex.split(cmd2) # split into args
# first process uses default stdin
ps1 = Popen(args1, stdout=PIPE)
# then use the output of the previous process as stdin
ps2 = Popen(args2, stdin=ps1.stdout, stdout=PIPE)
out, err = ps2.communicate()
print(out)

这次,结果是grep进程的单个僵尸进程(169731是python会话的pid:]

[reinski@myhost ~]$ ps -eF|grep 169731
reinski  169731 189499  0 37847  6024 198 17:51 pts/2    00:00:00 python
reinski  193999 169731  0     0     0 142 17:53 pts/2    00:00:00 [grep] <defunct>

所以,这仅仅是同一问题的另一种症状,还是我在这里做错了什么?

我有一个较旧的python 2.7.5脚本,它突然在Red Hat Enterprise Linux Server 7.6(Maipo)上出现问题。毕竟,它在Red Hat Enterprise Linux Server 7.4版上运行良好(...

python subprocess pipe
1个回答
0
投票

好吧,看来我刚刚从示例中发现了一个僵尸进程的解决方案:只需要做一个

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