Как запустить два цикла Python одновременно? - PullRequest
19 голосов
/ 13 августа 2010

Предположим, у меня есть следующее в Python

# A loop
for i in range(10000):
    Do Task A

# B loop
for i in range(10000):
    Do Task B

Как мне запустить эти циклы одновременно в Python?

Ответы [ 7 ]

25 голосов
/ 13 августа 2010

Если вы хотите параллелизма, вот очень простой пример:

from multiprocessing import Process

def loop_a():
    while 1:
        print("a")

def loop_b():
    while 1:
        print("b")

if __name__ == '__main__':
    Process(target=loop_a).start()
    Process(target=loop_b).start()

Это просто самый простой пример , который я мог бы себе представить.Обязательно прочитайте http://docs.python.org/library/multiprocessing.html, чтобы понять, что происходит.

Если вы хотите отправить данные обратно в программу, я бы порекомендовал использовать Очередь (которую, по моему опыту, проще всего использовать).

Вместо этого вы можете использовать поток, если не возражаете против глобальной блокировки интерпретатора .Процессы дороже создавать, но они обеспечивают истинный параллелизм.

12 голосов
/ 13 августа 2010

Почему вы хотите запустить два процесса одновременно? Это потому, что вы думаете, что они пойдут быстрее (есть хороший шанс, что они не будут). Почему бы не запустить задачи в одном цикле, например,

for i in range(10000):
    doTaskA()
    doTaskB()

Очевидный ответ на ваш вопрос - использовать потоки - см. Модуль python threading . Тем не менее, многопоточность является большой темой и имеет много подводных камней, поэтому прочтите ее, прежде чем идти по этому пути.

В качестве альтернативы вы можете запускать задачи в отдельных процессах, используя модуль python multiprocessing . Если обе задачи потребляют много ресурсов процессора, это позволит лучше использовать несколько ядер на вашем компьютере.

Существуют и другие варианты, такие как сопрограммы, тасклеты без стеков, гринлеты, CSP и т. Д., Но, не зная больше о Задаче A и Задаче B и о том, почему они должны выполняться одновременно, невозможно дать более конкретный ответ.

9 голосов
/ 17 декабря 2014

Существует множество возможных вариантов того, что вы хотели:

использовать цикл

Как отмечали многие, это самый простой способ.

for i in xrange(10000):
    # use xrange instead of range
    taskA()
    taskB()

Достоинства: легко понять и использовать, дополнительная библиотека не требуется.

Недостатки: задача B должна выполняться после задачи A или иным образом.Они не могут работать одновременно.

multiprocess

Еще одна мысль: запустить два процесса одновременно, python предоставляет многопроцессную библиотеку , следующее простоепример:

from multiprocessing import Process


p1 = Process(target=taskA, args=(*args, **kwargs))
p2 = Process(target=taskB, args=(*args, **kwargs))

p1.start()
p2.start()

достоинства: задачу можно запустить simultaneously в фоновом режиме, вы можете управлять задачами (завершать, останавливать их и т. д.), задачи могут обмениваться данными, могут быть синхронизированы, если они конкурируют с одними и теми же ресурсамии т.д.

недостатки: слишком тяжелые! ОС часто переключается между ними, у них есть свое собственное пространство данных, даже если данные избыточны.Если у вас много задач (скажем, 100 или более), это не то, что вы хотите.

Threading

Threading похож на процесс, только легкий.проверить этот пост .Их использование очень похоже:

import threading 


p1 = threading.Thread(target=taskA, args=(*args, **kwargs))
p2 = threading.Thread(target=taskB, args=(*args, **kwargs))

p1.start()
p2.start()

сопрограммы

библиотеки, такие как greenlet и gevent, предоставляют нечто, называемое сопрограммой, которое должно быть быстрее, чем многопоточность.Примеры не предоставлены, пожалуйста, Google, как использовать их, если вы заинтересованы.

достоинства: более гибкий и легкий

недостатки: требуется дополнительная библиотека, обучение.

7 голосов
/ 13 августа 2010
from threading import Thread
def loopA():
    for i in range(10000):
        #Do task A
def loopB():
    for i in range(10000):
        #Do task B
threadA = Thread(target = loopA)
threadB = Thread(target = loobB)
threadA.run()
threadB.run()
# Do work indepedent of loopA and loopB 
threadA.join()
threadB.join()
1 голос
/ 13 августа 2010

Вы можете использовать многопоточность или многопроцессорность .

1 голос
/ 13 августа 2010

Как насчет: цикл для i в диапазоне (10000): выполнить задачу A, выполнить задачу B?Без дополнительной информации у меня нет лучшего ответа.

0 голосов
/ 02 апреля 2016

Я считаю, что использование подмодуля «пул» в «многопроцессорной» прекрасно работает для одновременного выполнения нескольких процессов в скрипте Python.

См. Раздел: Использование пула работников

Внимательно посмотрите на "# запуск нескольких оценок асинхронно может использовать больше процессов" в примере. Как только вы поймете, что делают эти строки, следующий пример, который я построил, будет иметь большой смысл.

import numpy as np
from multiprocessing import Pool

def desired_function(option, processes, data, etc...):
    # your code will go here. option allows you to make choices within your script
    # to execute desired sections of code for each pool or subprocess.

    return result_array   # "for example"


result_array = np.zeros("some shape")  # This is normally populated by 1 loop, lets try 4.
processes = 4
pool = Pool(processes=processes)
args = (processes, data, etc...)    # Arguments to be passed into desired function.

multiple_results = []
for i in range(processes):          # Executes each pool w/ option (1-4 in this case).
    multiple_results.append(pool.apply_async(param_process, (i+1,)+args)) # Syncs each.

results = np.array(res.get() for res in multiple_results)  # Retrieves results after
                                                           # every pool is finished!

for i in range(processes):
    result_array = result_array + results[i]  # Combines all datasets!

Код будет в основном запускать нужную функцию для заданного числа процессов. Вам нужно будет тщательно убедиться, что ваша функция может различать каждый процесс (поэтому я и добавил переменную "option".) Кроме того, это не обязательно должен быть массив, который заполняется в конце, но для моего примера, вот как я это использовал. Надеюсь, что это упрощает или помогает вам лучше понять мощь многопроцессорности в Python!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...