Подтвердить что ты не робот

Подождите окончания подпроцессов с несколькими параллельными заданиями

Я выполняю несколько подпроцессов из 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

существует класс, который может обрабатывать несколько подпроцессов? Проблема в том, что метод wait блокирует мою программу.

update. Я хочу показать прогресс во время вычисления: что-то вроде "4/7 подпроцесса завершено..."

Если вам интересно root скомпилировать С++ script и выполнить его.

4b9b3361

Ответ 1

Если ваша платформа не является Windows, вы, вероятно, можете выбрать против stdout-протоколов ваших подпроцессов. Затем ваше приложение блокируется до:

  • Один из зарегистрированных файловых дескрипторов имеет событие ввода-вывода (в этом случае нас интересует зависание на трубе stdout subprocess)
  • Время опроса

Непоследовательный пример с использованием epoll с Linux 2.6.xx:

import subprocess
import select

poller = select.epoll()
subprocs = {} #map stdout pipe 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

Ответ 2

Вы можете сделать что-то вроде этого:

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()

Процессы будут выполняться параллельно, и вы будете ждать их всех в конце.

Ответ 3

Как насчет

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)