Процессы Python Popen без связи завершаются быстрее

Я не совсем уверен, почему, но я, по сути, хочу запустить 2 процесса, поэтому я использую функцию Popen подпроцесса.

commands = ['command 1', 'command 2']
for command in commands:
    proc = Popen(command.split(' '))
    proc.communicate()       # line of interest

Команды представляют собой процессы рендеринга, поэтому по завершении они создают изображение в каталоге. Что странно, так это то, что когда я запускаю их с помощью Communic(), по существу, последовательно, они заканчиваются в ожидаемое время (примерно время 1 + время 2).

Однако, когда я запускаю их без сообщения(), что должно эффективно запускать их параллельно, для их завершения требуется НАМНОГО больше времени. Кто-нибудь понимает, почему может произойти такое поведение и как его исправить?


person Jared Joke    schedule 10.01.2014    source источник
comment
Это всего 2 команды или у вас их больше? Как выглядят ваши системные ресурсы, когда вы запускаете это -- например. Вы уверены, что не нажимаете swap с памятью или что-то в этом роде?   -  person mgilson    schedule 10.01.2014
comment
Да, на самом деле их всего 2 (работы по рендерингу, такие параллельные). Он не использует процессоры и не использует пространство подкачки. Кажется, ресурсов для этого более чем достаточно.   -  person Jared Joke    schedule 10.01.2014


Ответы (1)


Чтобы они работали параллельно, вам нужно создать экземпляр Popen несколько раз. Ваш пример предполагает, что вы общаетесь с процессами не через stdin, stdout или stderr, а через файлы. Предполагая это, вы можете использовать метод wait вместо communicate. Таким образом, результат может выглядеть следующим образом:

commands = [['command', '1'], ['command', '2']]
processes = [Popen(command) for command in commands]
# they are both running now
returncodes = [process.wait() for process in processes]
# successful if all returncodes are 0

Если ваши процессы рендеринга также написаны на Python, взгляните на модуль multiprocessing. Это может помочь распараллелить ваш код, используя несколько процессов, избегая конкуренции GIL.

Если вы действительно взаимодействуете со своими процессами, вам потребуется использовать более сложный механизм для мультиплексирования операций ввода-вывода. Здесь также может пригодиться модуль multiprocessing, но вы также можете реализовать связь с помощью asyncore или другой инфраструктуры ввода-вывода.

person Helmut Grohne    schedule 10.01.2014