我的脚本有两个循环:
ssh
进程,每个远程计算机都有一个进程;returncode
我看到,它们都按顺序运行——通过每个命令的打印输出确认——而我期望它们并行运行……我做错了什么?
date
: 运行 args 描述的命令。等待命令完成,然后返回 CompletedProcess 实例。 因此
pipes = {}
myhostname = os.uname()[1].lower()
for node in Nodes:
if node.lower() == myhostname:
cmd = '/bin/bash'
else:
cmd = ('ssh -q '
'-o PasswordAuthentication=no '
'-o StrictHostKeyChecking=no '
'%s /bin/bash') % node
pipe = subprocess.Popen(cmd.split(' '),
stdin = subprocess.PIPE, stdout = subprocess.PIPE,
stderr = subprocess.PIPE, close_fds = True,
encoding = locale.getlocale()[1])
pipe.stdin.write("""
date
sleep 1
date
exit""")
pipes[node] = pipe
logging.info('%d processes spawn, collecting outputs', len(pipes))
errCount = 0
for (node, pipe) in pipes.items():
out, err = pipe.communicate()
if err:
logging.warn('%s stderr: %s', node, err.strip())
if out:
logging.info('%s stdout: %s', node, out.strip())
if pipe.returncode != 0:
errCount += 1
logging.error('Got exit code %d from %s, increasing '
'error-count to %d', pipe.returncode, node, errCount)
不会启动另一个并行运行的线程。它只是生成一个子进程,等待结果并返回。对于您想要实现的目标,
线程模块可能更相关。
中等待,直到您对每个进程调用subprocess
,刷新并关闭每个进程的输入。您按顺序执行此操作,因此
communicate
命令按顺序运行,即使 date
进程始终并行运行。您可以在 ssh
之后立即添加 pipe.stdin.flush()
以获得所需的效果。write
冲洗客户端的管道。由于您的输出小于默认管道大小,因此它将被缓冲。作为副作用,我认为这会推迟进程的创建。
exit
被阻挡。如果您更改 pipe.communicate()
(至少在 Linux 上)以获得您期望的行为。