2017-01-06 5 views
0

Я хотел бы запустить серию команд (которые занимают много времени). Но я не хочу ждать завершения каждой команды. Как я могу это сделать на Python?Python создать подпроцесс и не ждать

Я смотрел на

os.fork() 

и

subprocess.popen() 

Не думаю, что это то, что мне нужно.

Код

def command1(): 
    wait(10) 

def command2(): 
    wait(10) 

def command3(): 
    wait(10) 

Я хотел бы назвать

command1() 
command2() 
command3() 

без необходимости ждать.

+0

Вы можете использовать [asyncio subprocess] (https://docs.python.org/3/library/asyncio-subprocess.html), если вы используете Python 3.4+ –

+0

Если ваши команды являются функциями python, вы можете рассмотрите темы: https://docs.python.org/2/library/threading.html.Это также зависит от того, что вы подразумеваете под «Я не хочу ждать» – doomyster

+1

Ну ... просто удалите «подожди» ... извините. :) Вы посмотрели на «многопроцессорность»? Вы можете начать процесс для каждой команды. Документация по умолчанию объясняет это довольно хорошо. –

ответ

2

Самый простой способ заключается в использовании Python собственного multiprocessing:

from multiprocessing import Process 

def command1(): 
    wait(10) 
... 

call1 = Process(target=command1, args=(...)) 
call1.start() 
... 

Этот модуль был введен обратно точно, чтобы облегчить нагрузку на контроль внешнего исполнения процесса функций, доступных в одной и той же кодовой базе, конечно, что можно было бы сделать, используя os.fork, subprocess. Мультипроцессор эмулирует, насколько это возможно, собственный интерфейс Python threading moudle. Одним из непосредственных преимуществ использования многопроцессорной обработки потоковой обработки является то, что это позволяет различным рабочим процессам использовать разные ядра ЦП, фактически работающие параллельно - в то время как потоковая передача, фактически, из-за ограничений по языковому дизайну, фактически ограничена одним исполнителем сразу , таким образом, используя одно ядро, даже когда доступно несколько.

Теперь обратите внимание, что все еще есть особенности - особенно, если вы, например, вызываете их из веб-запроса. Ответьте на этот вопрос в виде ответов на несколько дней назад: Stop a background process in flask without creating zombie processes

2

Использовать многопроцессорный модуль python.

def func(arg1): 
    ... do something ... 

from multiprocessing import Process 
p = Process(target=func, args=(arg1,), name='func') 
p.start() 

Полный Documentaion находится здесь: https://docs.python.org/2/library/multiprocessing.html

EDIT:

Вы можете также использовать модуль резьбе питона, если вы используете распределение JPython/CPython, как вы можете преодолеть GIL (Global Interpreter Lock) в этих распределениях.

https://docs.python.org/2/library/threading.html

+0

Вы должны исправить/уточнить ваше предложение о GIL. – moooeeeep

1

Этот пример может быть, подходит для вас:

#!/usr/bin/env python3 

import sys 
import os 
import time 

def forked(fork_func): 
    def do_fork(): 
     pid = os.fork() 
     if (pid > 0): 
      fork_func() 
      exit(0) 
     else: 
      return pid 
    return do_fork 

@forked 
def command1(): 
    time.sleep(2) 

@forked 
def command2(): 
    time.sleep(1) 

command1() 
command2() 
print("Hello") 

Вы просто использовать декоратора @forked для ваших функций.

Существует только одна проблема: когда основная программа закончена, она ждет окончания дочерних процессов.

+0

Это хороший пример, но он действительно только начинает изобретать колесо на том, что делает многопроцессорность Python, и если вы откроете для него документацию, вы обнаружите, что есть много вещей, чтобы заставить его работать правильно. Исходя из того, что 'os.fork' не работает на платформе Windows. – jsbueno

+0

Но да, у вас здесь очень хороший и простой пример. Спасибо, в любом случае. – jsbueno

+0

Я знаю многопроцессорный модуль. Только один, который он дает, является кросс-платформенным. Автор задал вопрос о запуске функций с минимальным синтаксисом во время разговора. Этот способ дает это. Существует возможность писать код с функциями «многопроцессорности» внутри 'do_fork()', и это лучше, я согласен. Но моя идея заключается в использовании декораторов для легкого синтаксиса, это не 'os.fork()' или 'multiprocess.Process()'. – ValeriyKr