首页 / PYTHON / Python子进程使用超时终止
Python子进程使用超时终止
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Python子进程使用超时终止,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2415字,纯文字阅读大概需要4分钟。
内容图文
![Python子进程使用超时终止](/upload/InfoBanner/zyjiaocheng/950/aa11107001e845fea3d8c043e7d9a15f.jpg)
我正在使用python中的子进程模块运行一些shell脚本.如果shell脚本运行得很长,我喜欢杀死子进程.我认为如果我将timeout = 30传递给我的run(..)语句就足够了.
这是代码:
try:
result=run(['utilities/shell_scripts/{0} {1} {2}'.format(
self.language_conf[key][1], self.proc_dir, config.main_file)],
shell=True,
check=True,
stdout=PIPE,
stderr=PIPE,
universal_newlines=True,
timeout=30,
bufsize=100)
except TimeoutExpired as timeout:
我用一些运行120s的shell脚本测试了这个调用.我预计子进程会在30秒后被杀死,但实际上这个过程正在完成120s脚本,而不是引发超时异常.现在问题如何通过超时杀死子进程?
解决方法:
文档明确指出应该杀死进程:
“The timeout argument is passed to Popen.communicate(). If the timeout expires, the child process will be killed and waited for. The TimeoutExpired exception will be re-raised after the child process has terminated.”
但是在你的情况下你使用的是shell = True,之前我已经看过类似的问题,因为阻塞过程是shell进程的子进程.
如果你正确地分解你的参数并且你的脚本有适当的shebang,我认为你不需要shell = True.你可以试试这个:
result=run(
[os.path.join('utilities/shell_scripts',self.language_conf[key][1]), self.proc_dir, config.main_file], # don't compose argument line yourself
shell=False, # no shell wrapper
check=True,
stdout=PIPE,
stderr=PIPE,
universal_newlines=True,
timeout=30,
bufsize=100)
请注意,我可以在Windows上轻松地重现此问题(使用Popen,但它是一样的):
import subprocess,time
p=subprocess.Popen("notepad",shell=True)
time.sleep(1)
p.kill()
=>记事本保持打开状态,可能是因为它设法从父shell进程中分离出来.
import subprocess,time
p=subprocess.Popen("notepad",shell=False)
time.sleep(1)
p.kill()
=>记事本在1秒钟后关闭
有趣的是,如果你删除time.sleep(),kill()甚至可以使用shell = True,因为它成功杀死了启动记事本的shell.
我并不是说你有完全相同的问题,我只是在证明shell = True是邪恶的,原因很多,并且无法杀死/超时这个过程是另一个原因.
但是,如果出于某种原因需要shell = True,则可以使用psutil最终杀死所有子项.在这种情况下,最好使用Popen,以便直接获得进程ID:
import subprocess,time,psutil
parent=subprocess.Popen("notepad",shell=True)
for _ in range(30): # 30 seconds
if parent.poll() is not None: # process just ended
break
time.sleep(1)
else:
# the for loop ended without break: timeout
parent = psutil.Process(parent.pid)
for child in parent.children(recursive=True): # or parent.children() for recursive=False
child.kill()
parent.kill()
(来源:how to kill process and child processes from python?)
该示例也会杀死记事本实例.
内容总结
以上是互联网集市为您收集整理的Python子进程使用超时终止全部内容,希望文章能够帮你解决Python子进程使用超时终止所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。