我在运行Python 2.6的Linux机器上运行多个命令,这可能需要一些时间。
因此,我使用subprocess.Popen
类和process.communicate()
方法并行执行多个命令组,并在执行后立即捕获输出。
def run_commands(commands, print_lock):
# this part runs in parallel.
outputs = []
for command in commands:
proc = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
output, unused_err = proc.communicate() # buffers the output
retcode = proc.poll() # ensures subprocess termination
outputs.append(output)
with print_lock: # print them at once (synchronized)
for output in outputs:
for line in output.splitlines():
print(line)
在别的地方,它的名字是这样的:
processes = []
print_lock = Lock()
for ...:
commands = ... # a group of commands is generated, which takes some time.
processes.append(Thread(target=run_commands, args=(commands, print_lock)))
processes[-1].start()
for p in processes: p.join()
print('done.')
预期的结果是,一组命令的每个输出在并行执行时同时显示。
但是从第二个输出组(当然,成为第二个的线程由于调度的不确定性而改变)开始,它开始打印,没有换行符,并且添加的空格数与前一行中打印的字符数相同,并且输入回声被关闭——终端状态是“混乱”或“崩溃”。(如果我发出reset
shell命令,它将恢复正常。)
起初,我试图从'\r'
的处理中找到原因,但这不是原因。正如您在我的代码中所看到的,我使用splitlines()
正确地处理了它,并且通过对输出应用repr()
函数确认了这一点。
我认为原因是在stdout/stderr的Popen
和communicate()
中同时使用管道。我在Python2.7中尝试了check_output
快捷方法,但没有成功。当然,如果我序列化所有命令执行和打印,则不会出现上述问题。
有没有更好的方法来并行处理Popen
和communicate()
?
我不确定run_命令实际需要做什么,但它似乎只是对子进程进行轮询,忽略返回代码并继续循环。当您到达打印输出的部分时,您如何知道子流程已经完成?
在您的示例代码中,我注意到您使用了:
部分解决“使用
会有帮助的。
一个最终的结果灵感来自J.F.Sebastian的评论。
http://bitbucket.org/daybreaker/kaist-cs443/src/247f9ecf3cee/tools/manage.py
这似乎是一个Python bug。
相关问题 更多 >
编程相关推荐