Ваша проблема в том, как вы настраиваете процессы.Вы не запускаете процессы параллельно, даже если вы так думаете.Вы фактически запускаете их, когда вы добавляете их к 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
передается исполнителю.И когда результаты будут готовы, вызывается обратный вызов, чтобы вывести результат на экран.