执行并行 .py 脚本
Execute parallell .py scripts
说我有 scrapper_1.py , scrapper_2.py, scrapper_3.py.
我 运行 现在它来自 pycharm run/execute 每个单独的方式,这样我可以在任务管理器中看到 3 python.exe 正在执行。
现在我正在尝试编写一个主脚本,比如 scrapper_runner.py 将此报废程序作为模块导入,并且 运行 它们都是并行的而不是顺序的。
我尝试了来自各种 SO 帖子的子进程、多处理甚至 os.system 的示例......但没有任何运气......从日志中它们都是 运行 按顺序和任务管理器我只看到一次 python.exe 次执行。
这种流程的模式是否正确?
编辑:1(尝试使用 concurrent.futures ProcessPoolExecutor)按顺序 运行ns。
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())
python 中的子进程可能会或可能不会显示为单独的进程,具体取决于您的 OS 和任务管理器。例如linux中的htop
,将在树视图中显示父进程下的子进程。
我建议看一下 python 中 multiprocessing
模块的深入教程:https://pymotw.com/2/multiprocessing/basics.html
但是,如果 python 的 multiprocessing/threading 内置方法对您不起作用或没有意义,您可以通过使用 bash 调用来实现您想要的结果你的 python 脚本。以下 bash 脚本会产生附加的屏幕截图。
#!/bin/sh
./py1.py &
./py2.py &
./py3.py &
说明:每个调用结束时的 &
告诉 bash 到 运行 每个调用作为后台进程。
您的问题在于如何设置流程。你不是 运行 并行的进程,即使你认为你是。你实际上是 运行 他们,当你将它们添加到 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
提交给执行程序时发生。并且,当结果准备就绪时,将调用回调以将结果打印到屏幕。
说我有 scrapper_1.py , scrapper_2.py, scrapper_3.py.
我 运行 现在它来自 pycharm run/execute 每个单独的方式,这样我可以在任务管理器中看到 3 python.exe 正在执行。
现在我正在尝试编写一个主脚本,比如 scrapper_runner.py 将此报废程序作为模块导入,并且 运行 它们都是并行的而不是顺序的。
我尝试了来自各种 SO 帖子的子进程、多处理甚至 os.system 的示例......但没有任何运气......从日志中它们都是 运行 按顺序和任务管理器我只看到一次 python.exe 次执行。
这种流程的模式是否正确?
编辑:1(尝试使用 concurrent.futures ProcessPoolExecutor)按顺序 运行ns。
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())
python 中的子进程可能会或可能不会显示为单独的进程,具体取决于您的 OS 和任务管理器。例如linux中的htop
,将在树视图中显示父进程下的子进程。
我建议看一下 python 中 multiprocessing
模块的深入教程:https://pymotw.com/2/multiprocessing/basics.html
但是,如果 python 的 multiprocessing/threading 内置方法对您不起作用或没有意义,您可以通过使用 bash 调用来实现您想要的结果你的 python 脚本。以下 bash 脚本会产生附加的屏幕截图。
#!/bin/sh
./py1.py &
./py2.py &
./py3.py &
说明:每个调用结束时的 &
告诉 bash 到 运行 每个调用作为后台进程。
您的问题在于如何设置流程。你不是 运行 并行的进程,即使你认为你是。你实际上是 运行 他们,当你将它们添加到 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
提交给执行程序时发生。并且,当结果准备就绪时,将调用回调以将结果打印到屏幕。