python安全管理子进程-subprocess
来源:互联网 发布:mac如何打开zip文件 编辑:程序博客网 时间:2024/04/28 01:25
经常会用到python去调用外部 工具或者命令去干活
有的时候子进程并不按预期退出
比如,子进程由于某种原因挂在那里,
这时候也许,我们有这样一种需求:需要父进程对子进程有监控动作,即,超过一定的时间,就不再等待子进程自己退出,而是去kill子进程,回收资源
以下会列出几张实现方法
1.os.system
http://docs.python.org/library/os.html
- Python 2.5.2 (r252:60911, Jan 4 2009, 17:40:26)
- [GCC 4.3.2] on linux2
- Type "help", "copyright", "credits" or "license" for more information.
- >>> import os
- >>> os.system("date")
- Wed Jun 10 19:34:23 CST 2009
- 0
- >>>
Python 2.5.2 (r252:60911, Jan 4 2009, 17:40:26)[GCC 4.3.2] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> import os>>> os.system("date")Wed Jun 10 19:34:23 CST 20090>>>
其实是执行 linux shell 命令
- $ date
- Wed Jun 10 19:36:02 CST 2009
$ dateWed Jun 10 19:36:02 CST 2009
缺点:
A. os.system() 是新起一个shell去干活的,对系统的开销比较大
B. 获得输出等信息比较麻烦,不能与外部命令或工具交互
C. 无法控制,(如果调用的外部命令,挂死或者执行时间很长),主进程无法控制os.system(), 因为调用os.system(cmd) 调用进程会block, until os.system() 自己退出
2.commands
[url]
http://docs.python.org/library/commands.html[/url]
- tommy@lab3:~$ python
- Python 2.5.2 (r252:60911, Jan 4 2009, 17:40:26)
- [GCC 4.3.2] on linux2
- Type "help", "copyright", "credits" or "license" for more information.
- >>> import commands
- >>> dir(commands)
- ['__all__', '__builtins__', '__doc__', '__file__', '__name__', 'getoutput', 'getstatus', 'getstatusoutput', 'mk2arg', 'mkarg']
- >>> commands.getoutput("date")
- 'Wed Jun 10 19:39:57 CST 2009'
- >>>
- >>> commands.getstatusoutput("date")
- (0, 'Wed Jun 10 19:40:41 CST 2009')
tommy@lab3:~$ pythonPython 2.5.2 (r252:60911, Jan 4 2009, 17:40:26)[GCC 4.3.2] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> import commands>>> dir(commands)['__all__', '__builtins__', '__doc__', '__file__', '__name__', 'getoutput', 'getstatus', 'getstatusoutput', 'mk2arg', 'mkarg']>>> commands.getoutput("date")'Wed Jun 10 19:39:57 CST 2009'>>>>>> commands.getstatusoutput("date")(0, 'Wed Jun 10 19:40:41 CST 2009')
优点:
A. 容易获得外部命令的输出,已经退出状态
缺点:
同os.system()中的B,C
3.subprocess
http://docs.python.org/library/subprocess.html
- tommy@lab3:~$ python
- Python 2.5.2 (r252:60911, Jan 4 2009, 17:40:26)
- [GCC 4.3.2] on linux2
- Type "help", "copyright", "credits" or "license" for more information.
- >>> import subprocess
- >>> dir(subprocess)
- ['CalledProcessError', 'MAXFD', 'PIPE', 'Popen', 'STDOUT', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '_active', '_cleanup', '_demo_posix', '_demo_windows', 'call', 'check_call', 'errno', 'fcntl', 'gc', 'list2cmdline', 'mswindows', 'os', 'pickle', 'select', 'signal', 'sys', 'traceback', 'types']
- >>> Popen = subprocess.Popen(["date"])
- Wed Jun 10 19:48:41 CST 2009
- >>> Popen.pid
- 24723
- >>>
tommy@lab3:~$ pythonPython 2.5.2 (r252:60911, Jan 4 2009, 17:40:26)[GCC 4.3.2] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> import subprocess>>> dir(subprocess)['CalledProcessError', 'MAXFD', 'PIPE', 'Popen', 'STDOUT', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '_active', '_cleanup', '_demo_posix', '_demo_windows', 'call', 'check_call', 'errno', 'fcntl', 'gc', 'list2cmdline', 'mswindows', 'os', 'pickle', 'select', 'signal', 'sys', 'traceback', 'types']>>> Popen = subprocess.Popen(["date"])Wed Jun 10 19:48:41 CST 2009>>> Popen.pid24723>>>
优点:
看文档吧,可以支持和子进程交互等等
虽然 python2.6中的subprocess模块增加了
kill()
terminate()
来控制子进程退出
但是在实际的使用过程中会发现
如果子进程并不是自己退出,而是调用 kill()/terminate() 给子进程发信退出
通过 top 或者 ps -A 看到,子进程的确是释放资源了,但是却变成了 zombie(僵尸进程)
于是分析 subprocess.py模块
- 1201
- 1202 def send_signal(self, sig):
- 1203 """Send a signal to the process
- 1204 """
- 1205 os.kill(self.pid, sig)
- 1206
- 1207 def terminate(self):
- 1208 """Terminate the process with SIGTERM
- 1209 """
- 1210 self.send_signal(signal.SIGTERM)
- 1211
- 1212 def kill(self):
- 1213 """Kill the process with SIGKILL
- 1214 """
- 1215 self.send_signal(signal.SIGKILL)
12011202 def send_signal(self, sig):1203 """Send a signal to the process1204 """1205 os.kill(self.pid, sig)12061207 def terminate(self):1208 """Terminate the process with SIGTERM1209 """1210 self.send_signal(signal.SIGTERM)12111212 def kill(self):1213 """Kill the process with SIGKILL1214 """1215 self.send_signal(signal.SIGKILL)
程序仅仅是 调用 os.kill(self.pid, sig) 向子进程发送了一个信号后,标准subprocess.py库 父进程并没有显示区 wait() 子进程,导致了 zombie(僵尸进程) 的生成
所以问题找到,
修改subprocess.py模块,显然不妥,
那就封装一下(继承subprocess),
我是用这个subprocess去调用mencoder 做批量转码,所以为子进程超时,要有很好控制,
具体实现见附件
显示的封装成两个函数
1.
shell_2_tty(_cmd=cmds, _cwd=None, _timeout=10*60)
# _cmd 是要执行的外面命令行,要是一个 list, 如果是str,shell=True,会启动一个新的shell去干活的,这样,不利于进程的控制
# _cwd 是执行这个命令行前,cd到这个路径下面,这个,对我的用应很重要,如果不需要可以用默认值
# _timeout 这个是主角,设置超时时间(秒单位),从真重执行命令行开始计时,墙上时间超过 _timeout后,父进程会kill掉子进程,回收资源,并避免产生 zombie(僵尸进程)
# 并将调用的命令行输出,直接输出到stdout,即是屏幕的终端上,
(如果对输出比较讨厌,可以将 stdout = open("/dev/null", "w"), stderr=open("/dev/null"),等等)
2.
shell_2_tempfile(_cmd=cmds, _cwd=None, _timeout=10)
类同1,主要是增加,对命令行的输出,捕获,并返回给父进程,留作分析
------------------------
- python安全管理子进程-subprocess
- python安全管理子进程-subprocess
- python 子进程subprocess
- Python 子进程 (subprocess包)
- Python子进程 subprocess模块
- Python子进程 (subprocess包)
- python子进程模块:subprocess
- python中的subprocess子进程
- Python模块学习 ---- subprocess 创建子进程
- python 使用 subprocess.Popen() 调用子进程
- Python模块学习 ---- subprocess 创建子进程
- Python模块整理:子进程模块subprocess
- Python模块学习 ---- subprocess 创建子进程
- Python模块学习 ---- subprocess 创建子进程
- Python模块学习 ---- subprocess 创建子进程
- Python模块学习 ---- subprocess 创建子进程
- Python标准库:子进程 (subprocess包)
- Python subprocess.Popen子进程管道阻塞
- Android UI设计 评分控件RatingBar用法
- 43.德国投资渠道如何查询?
- tomcat性能优化及乱码解决
- opencv检测运动物体的基础_特征提取
- objective-c一些需要记住的概念
- python安全管理子进程-subprocess
- 在android里如何代码调用系统短信发送界面
- jfreechart
- 静态构造函数
- Python 调用shell脚本
- nutch OnlinCuster 结果集聚合分类插件
- js获取当前日期时间和其他操作
- jquery artTxtCount 文本框输入字数提示
- jquery 滚动条动态图片加载