最近写完一个脚本后发现运行时linux上会出现一个僵尸进程。定位到改脚本,最后发现是因为popen处理不当引起的。僵尸进程类似如下。僵尸进程 defunct 的存在,虽然不占用内存和 CPU,但是会在进程任务管理树上占用一个宝贵的节点。这样就造成了进程名额的资源浪费,所以一定得处理僵尸进程!
zhangnq@ubuntu:~$ ps aux|grep -w 'Z' zhangnq 13430 0.0 0.0 0 0 pts/1 Z+ 19:37 0:00 [sh] zhangnq 13509 0.0 0.0 11068 956 pts/2 R+ 19:37 0:00 grep --color=auto -w Z
下面是产生僵尸进程的例子。
调用os模块,使用popen方法执行一个命令,可以看到在进程中产生了一个僵尸进程。如果关掉这个进程,只需要在后面加入close()函数即可。
>>> r_ls.close()
如果使用subprocess模块,在调用popen的时候也需要注意。
代码:
#!/usr/bin/env python import os import time import subprocess import sys if __name__ == '__main__': ts = int(time.time()) args='-c %d -W %d' % (1,1) ping_command = ['ping','192.168.188.1',args] ping_result=subprocess.Popen(ping_command,stdout=subprocess.PIPE, stderr=subprocess.STDOUT) tm_avg_list=ping_result.stdout.readlines()[-1].strip().split('/') #ping_result.wait() if len(tm_avg_list) > 1: tm_avg=tm_avg_list[4] else: tm_avg=1000 print("net.ping.avg %d %s host=gateway from_host=112") % (ts,tm_avg) while True: time.sleep(10)
以上代码如果注销wait()函数,那么进程中会存在一个僵尸进程。在使用 popen 函数后,我们需要调用 wait 函数(等待子进程中断或结束),否则就会产生僵尸进程。
wait() 会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用 wait() 时子进程已经结束,则 wait() 会立即返回子进程结束状态值。子进程的结束状态值会由参数 status 返回,而子进程的进程识别码也会一快返回。
测试:
#没有等待 >>> ping_result=subprocess.Popen('ping 192.168.188.1 -c 10 -W 1',shell=True,stdout=subprocess.PIPE, stderr=subprocess.STDOUT) >>> print ping_result #等待子进程结束 >>> ping_result=subprocess.Popen('ping 192.168.188.1 -c 10 -W 1',shell=True,stdout=subprocess.PIPE, stderr=subprocess.STDOUT) >>> ping_result.wait() >>> print ping_result
参考连接:http://blog.csdn.net/sky_qing/article/details/22296827