我正在编写一个python脚本,它在后台启动程序,然后监视程序是否遇到错误。我使用subprocess模块来启动进程并保留正在运行的程序的列表。在
processes.append((subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE), command))
我发现,当我试图通过对子进程对象调用communication来监视程序时,主程序会等待程序完成。我尝试过使用poll(),但这无法访问导致崩溃的错误代码,我希望解决此问题并重试打开进程。 runningProcesses是一个元组列表,其中包含subprocess对象和与之关联的命令。在
def monitorPrograms(runningProcesses):
for program in runningProcesses:
temp = program[0].communicate()
if program[0].returncode:
if program[0].returncode == 1:
print "Program exited successfully."
else:
print "Whoops, something went wrong. Program %s crashed." % program[0].pid
当我试图在不使用communicate的情况下获取返回代码时,程序的崩溃没有注册。 我是必须使用线程来并行地运行通信,还是有一种更简单的方法我没有?在
根据我的研究,最好的方法是使用线程。Here's an article我在创建自己的包以解决此问题时引用的。在
这里使用的基本方法是旋转不断请求子进程调用的日志输出(最后是退出状态)的线程。在
这是我自己的一个“接收者”的例子:
现在让接收器旋转的代码:
^{pr2}$CommandOutput只是一个命名元组,它使引用我关心的数据变得容易。在
你会注意到我有一个“wait_for_complete”方法,它等待接收方将complete设置为True。一旦完成,execute方法调用流程.投票()以获取退出代码。现在我们有了所有的stdout/stderr和进程的状态代码。在
不需要使用线程来监视多个进程,特别是如果不使用它们的输出(使用^{} instead of ^{} to hide the output ),请参见Python threading multiple bash subprocesses?
您的主要问题是} processes statuses 。在
Popen.poll()
用法不正确。如果它返回None
;这意味着进程仍在运行,您应该调用它,直到获得非None值。这是一个类似于你的案例code example that prints ^{如果您确实想将子进程的stdout/stderr作为字符串获取,那么可以使用threads, async.io。在
如果您在Unix上,并且控制了可能产生子进程的所有代码,那么您可以避免轮询并自己处理
SIGCHLD
。asyncio
stdlib库可以处理SIGCHLD
。你也可以implement it manually, though it might be complicated。在相关问题 更多 >
编程相关推荐