python subprocess使用记录

前几天发现服务器上有几个zombie进程,搜索了一下(ps -ef | grep defunct),僵尸进程的父进程是以前写的python同步脚本。

仔细看了下代码,发现在这:

sub = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# other codes

对,父进程开启了子进程后,并无任何动作,子进程执行完成后成为一个僵尸进程。

解决方法很简单,父进程wait子进程即可,但因为标准输出和标准错误输出是管道方式(PIPE),直接使用wait()有可能会导致管道堵塞,python官方文档亦有以下叙述:

Warning
 This will deadlock when using stdout=PIPE and/or stderr=PIPE and the child process generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use communicate() to avoid that.

官方建议适用communicate方法,于是修改代码如下:

sub = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
out, err = sub.communicate()

另外一种修改方式,适用于不关心子进程返回结果的场景,可以将STDOUT和STDERR输出结果定向到/dev/dull去,再调用wait()即可,如下:

sub = subprocess.Popen(cmd, shell=True, stdout=open("/dev/null", "w"), stderr=subprocess.STDOUT)
sub.wait()

因为需要子进程的处理信息,选用了第一种方法。重新启动python脚本,不再出现僵尸进程的问题了。


你可能感兴趣的:(python,subprocess,僵尸进程)