下面的代码尝试并行运行多个命令,每个命令都有一个超时。如果处理未通过超时完成,则将其停止(我正在使用Terminate())。
问题是终止后(返回码设置为-ve),communication()方法挂起,当强制退出(Ctrl + C)时,显示以下错误。
(stdout, stderr) = proc.communicate()
File "python3.7/subprocess.py", line 926, in communicate
stdout = self.stdout.read()
procList = []
for app in appList:
try:
p = subprocess.Popen(app['command'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
procList.append((app, p))
except Exception as e:
print(e)
start = time.time()
while len(procList):
time.sleep(30)
try:
for app, proc in procList:
if (time.time() - start > app['timeoutSec']):
proc.terminate()
if proc.poll() is not None and app['mailSent'] == 0:
(stdout, stderr) = proc.communicate() #Hangs here is the process is terminated
send_results_mail('Execution Completed or Terminated')
app['mailSent'] = 1
except subprocess.SubprocessError as e:
print(e)
procList = [(app, proc) for (app, proc) in procList if app['mailSent'] == 0]
不能保证proc.terminate()完全杀死Linux / Mac上的进程。目前尚不清楚您使用的是Windows还是Linux或Mac。
在Python 3的文档中,他们有一个非常不错的示例,该示例显示了对proc.communicate()使用超时来避免不响应Terminate()的进程,最后使用kill()。就您而言,您可能想采用这种模式?
来源:https://docs.python.org/3.7/library/subprocess.html#subprocess.Popen.communicate
proc = subprocess.Popen(...)
try:
outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
proc.kill()
outs, errs = proc.communicate()
您的解决方案可能会更简单,如果您不关心正常关闭孩子,您可以简单地kill()
他们,然后运行proc.communicate(timeout=1)
短暂等待他们的输出。