等待多个并行作业的子进程结束

Rug*_*rra 12 python subprocess

我正在并行运行python中的一些子进程.我想等到每个子进程都完成了.我正在做一个非优雅的解决方案:

runcodes = ["script1.C", "script2.C"]
ps = []
for script in runcodes:
  args = ["root", "-l", "-q", script]
  p = subprocess.Popen(args)
  ps.append(p)
while True:
  ps_status = [p.poll() for p in ps]
  if all([x is not None for x in ps_status]):
    break
Run Code Online (Sandbox Code Playgroud)

是否有一个类可以处理多个子进程?问题是该wait方法阻止了我的程序.

更新:我想在计算过程中显示进度:类似"4/7子流程完成......"

如果你很好奇root编译c ++脚本并执行它.

nos*_*klo 9

你可以这样做:

runcodes = ["script1.C", "script2.C"]

ps = []
for script in runcodes:
    args = ["root", "-l", "-q", script]
    p = subprocess.Popen(args)
    ps.append(p)

for p in ps:
    p.wait()
Run Code Online (Sandbox Code Playgroud)

这些过程将并行运行,您将在最后等待所有这些过程.

  • 是的,问题是我不能在执行期间编写`#process finished`,因为假设第一个子进程非常慢,p等于第一个`ps`并且python正在等待并冻结直到第一个完成; python无法写入除第一个之外的所有子进程都已完成. (5认同)

Jer*_*own 9

如果您的平台不是Windows,则可以选择子进程的stdout管道.您的应用将阻止,直到:

  • 其中一个已注册的文件描述符有一个I/O事件(在这种情况下,我们对子进程的stdout管道上的挂起感兴趣)
  • 民意调查超时

使用epoll与Linux 2.6.xx的非充实示例:

import subprocess
import select

poller = select.epoll()
subprocs = {} #map stdout pipe's file descriptor to the Popen object

#spawn some processes
for i in xrange(5):
    subproc = subprocess.Popen(["mylongrunningproc"], stdout=subprocess.PIPE)
    subprocs[subproc.stdout.fileno()] = subproc
    poller.register(subproc.stdout, select.EPOLLHUP)

#loop that polls until completion
while True:
    for fd, flags in poller.poll(timeout=1): #never more than a second without a UI update
        done_proc = subprocs[fd]
        poller.unregister(fd)
        print "this proc is done! blah blah blah"
        ...  #do whatever
    #print a reassuring spinning progress widget
    ...
    #don't forget to break when all are done
Run Code Online (Sandbox Code Playgroud)


Mar*_*nas 7

怎么样

import os, subprocess
runcodes = ["script1.C", "script2.C"]
ps = {}
for script in runcodes:
    args = ["root", "-l", "-q", script]
    p = subprocess.Popen(args)
    ps[p.pid] = p
print "Waiting for %d processes..." % len(ps)
while ps:
    pid, status = os.wait()
    if pid in ps:
        del ps[pid]
        print "Waiting for %d processes..." % len(ps)