[英]Run subprocess in python and get stdout and kill process on timeout
这是我的代码,它启动一个子进程,等到它结束并返回stdout,或者发生超时并引发异常。 常用的是print(Run('python --version').execute())
class Run(object):
def __init__(self, cmd, timeout=2*60*60):
self.cmd = cmd.split()
self.timeout = timeout
self._stdout = b''
self.dt = 10
self.p = None
def execute(self):
print("Execute command: {}".format(' '.join(self.cmd)))
def target():
self.p = Popen(self.cmd, stdout=PIPE, stderr=STDOUT)
self._stdout = self.p.communicate()[0]
thread = Thread(target=target)
thread.start()
t = 0
while t < self.timeout:
thread.join(self.dt)
if thread.is_alive():
t += self.dt
print("Running for: {} seconds".format(t))
else:
ret_code = self.p.poll()
if ret_code:
raise AssertionError("{} failed.\nretcode={}\nstdout:\n{}".format(
self.cmd, ret_code, self._stdout))
return self._stdout
else:
print('Timeout {} reached, kill task, pid={}'.format(self.timeout, self.p.pid))
self.p.terminate()
thread.join()
raise AssertionError("Timeout")
问题是以下情况。 我启动的进程产生了更多的子进程。 因此,当达到超时时,我使用self.p.terminate()
杀死了主进程(使用我的班级淘汰的那个主进程self.p.terminate()
,子self.p.terminate()
仍然存在,我的代码挂在了self._stdout = self.p.communicate()[0]
。 如果我手动终止所有子进程,执行将继续。
当我杀死整个进程树而不是self.p.terminate()
时,我尝试了解决方案。
如果主要过程本身及其子项独立存在,并且我也没有找到并杀死它们的能力,那么这也不起作用。 但是它们阻止了self.p.communicate()
。
有办法有效解决这个问题吗?
您可以使用PySys框架中的ProcessWrapper-它以跨平台的方式提供了很多作为抽象的功能,即
import sys, os
from pysys.constants import *
from pysys.process.helper import ProcessWrapper
from pysys.exceptions import ProcessTimeout
command=sys.executable
arguments=['--version']
try:
process = ProcessWrapper(command, arguments=arguments, environs=os.environ, workingDir=os.getcwd(), stdout='stdout.log', stderr='stderr.log', state=FOREGROUND, timeout=5.0)
process.start()
except ProcessTimeout:
print "Process timeout"
process.stop()
如果感兴趣的话,可以在SourceForge( http://sourceforge.net/projects/pysys/files/和http://pysys.sourceforge.net/ )上找到。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.