[python communication()在进程终止()之后挂起

问题描述 投票:0回答:1

下面的代码尝试并行运行多个命令,每个命令都有一个超时。如果处理未通过超时完成,则将其停止(我正在使用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]
python subprocess timeout terminate
1个回答
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)短暂等待他们的输出。

© www.soinside.com 2019 - 2024. All rights reserved.