Выполнять параллельные .py скрипты - PullRequest
0 голосов
/ 14 октября 2018

Скажите, что у меня есть scrapper_1.py, scrapper_2.py, scrapper_3.py.

То, как я сейчас запускаю его, запускает / выполняет каждый из pycharm по-отдельности, так что я вижу 3 python.exeвыполняется в диспетчере задач.

Теперь я пытаюсь написать мастер-скрипт, скажем scrapper_runner.py, который импортирует эти скребки как модули и запускает их все параллельно, а не последовательно.

Я пробовал примеры с подпроцессом, многопроцессорная обработка даже os.system из различных сообщений SO ... но без какой-либо удачи ... из журналов все они запускаются последовательно, а из диспетчера задач я вижу только одно выполнение python.exe.

Правильно ли этошаблон для такого типа процесса?

РЕДАКТИРОВАТЬ: 1 (при попытке с concurrent.futures ProcessPoolExecutor) он выполняется последовательно.

from concurrent.futures import ProcessPoolExecutor

import scrapers.scraper_1 as scraper_1
import scrapers.scraper_2 as scraper_2
import scrapers.scraper_3 as scraper_3

## Calling method runner on each scrapper_x to kick off processes
runners_list = [scraper_1.runner(), scraper_1.runner(), scraper_3.runner()]



if __name__ == "__main__":


    with ProcessPoolExecutor(max_workers=10) as executor:
        for runner in runners_list:
            future = executor.submit(runner)
            print(future.result())

Ответы [ 2 ]

0 голосов
/ 14 октября 2018

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

То, что вы хотите сделать, это добавить функции к runners_list, не выполняя их, затем запустите их в вашей многопроцессорной обработке pool.Способ достижения этого заключается в добавлении ссылок на функции, то есть имени функций.Для этого не следует включать в себя паратезы, так как это синтаксис для вызова функций, а не просто их именования.

Кроме того, для выполнения фьючерсов асинхронно, прямой вызов невозможенна future.result, так как это заставит код выполняться последовательно, чтобы гарантировать, что результаты доступны в той же последовательности, что и вызываемые функции.

Это означает, что смысл вашей проблемы равен

from concurrent.futures import ProcessPoolExecutor

import scrapers.scraper_1 as scraper_1
import scrapers.scraper_2 as scraper_2
import scrapers.scraper_3 as scraper_3

## NOT calling method runner on each scrapper_x to kick off processes
## Instead add them to the list of functions to be run in the pool
runners_list = [scraper_1.runner, scraper_1.runner, scraper_3.runner]

# Adding callback function to call when future is done.
# If result is not printed in callback, the future.result call will
# serialize the call sequence to ensure results in order
def print_result(future):
    print(future.result)

if __name__ == "__main__":
    with ProcessPoolExecutor(max_workers=10) as executor:
        for runner in runners_list:
            future = executor.submit(runner)
            future.add_done_callback(print_result)

Как видите, здесь вызов бегунов происходит не при создании списка, а позже, когда runner передается исполнителю.И когда результаты будут готовы, вызывается обратный вызов, чтобы вывести результат на экран.

0 голосов
/ 14 октября 2018

Подпроцесс в python может отображаться или не отображаться как отдельный процесс, в зависимости от вашей ОС и диспетчера задач.Например, htop в linux будет отображать подпроцессы под родительским процессом в древовидном представлении.

Я рекомендую взглянуть на это подробное руководство по модулю multiprocessing в python: https://pymotw.com/2/multiprocessing/basics.html

Однако, если встроенные в Python методы многопроцессорной обработки / многопоточности не работают или не имеют смысла для вас, вы можете достичь желаемого результата, используя bash для вызова ваших сценариев Python.Следующий скрипт bash приводит к прикрепленному скриншоту.

#!/bin/sh
./py1.py &
./py2.py &
./py3.py &

parallel python scripts

Объяснение: & в конце каждого вызова заставляет bash работатькаждый вызов в качестве фонового процесса.

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