Python 执行parallel.py脚本

Python 执行parallel.py脚本,python,subprocess,python-multiprocessing,python-multithreading,python-module,Python,Subprocess,Python Multiprocessing,Python Multithreading,Python Module,比如说我有刮刀1.py,刮刀2.py,刮刀3.py 我现在运行它的方式是从pycharm分别运行/执行,这样我可以在TaskManager中看到3 python.exe正在执行 现在我正在尝试编写一个主脚本,比如scraster_runner.py,它将这个scraster作为模块导入,并并行运行,而不是按顺序运行 我从各种SO帖子中尝试了子流程、多处理甚至os.system的示例。。。但是没有任何运气。。。从日志中,它们都是按顺序运行的,从任务管理器中,我只看到一个python.exe执行 这

比如说我有刮刀1.py,刮刀2.py,刮刀3.py

我现在运行它的方式是从pycharm分别运行/执行,这样我可以在TaskManager中看到3 python.exe正在执行

现在我正在尝试编写一个主脚本,比如scraster_runner.py,它将这个scraster作为模块导入,并并行运行,而不是按顺序运行

我从各种SO帖子中尝试了子流程、多处理甚至os.system的示例。。。但是没有任何运气。。。从日志中,它们都是按顺序运行的,从任务管理器中,我只看到一个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())

python中的子进程可能会也可能不会显示为单独的进程,这取决于您的操作系统和任务管理器<例如,linux中的code>htop将在树视图中的父进程下显示子进程

我建议大家看一看关于python中的
多处理模块的深入教程:

但是,如果python内置的多处理/线程方法不起作用或对您没有意义,那么您可以通过使用bash调用python脚本来实现所需的结果。下面的bash脚本将生成附加的屏幕截图

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


说明:每个调用结束时的
&
告诉bash将每个调用作为后台进程运行。

python中的子进程可能会或可能不会显示为单独的进程,具体取决于您的操作系统和任务管理器<例如,linux中的code>htop
将在树视图中的父进程下显示子进程

我建议大家看一看关于python中的
多处理模块的深入教程:

但是,如果python内置的多处理/线程方法不起作用或对您没有意义,那么您可以通过使用bash调用python脚本来实现所需的结果。下面的bash脚本将生成附加的屏幕截图

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


说明:每个调用结束时的
&
告诉bash将每个调用作为后台进程运行。

您的问题在于如何设置进程。您没有并行运行这些进程,即使您认为是这样。当您将它们添加到
运行程序\u列表中时,您实际上正在运行它们,然后将每个运行程序的结果作为多个进程并行运行

您要做的是将函数添加到
运行程序列表中,而不执行它们,然后在多处理
池中执行它们。实现这一点的方法是添加函数引用,即函数的名称。要做到这一点,您不应该包括paranthese,因为这是调用函数的语法,而不仅仅是命名函数

此外,为了让future异步执行,不可能直接调用
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
提交给执行器时调用运行程序。当结果准备就绪时,调用回调函数,将结果打印到屏幕上。

您的问题在于如何设置流程。您没有并行运行这些进程,即使您认为是这样。当您将它们添加到
运行程序\u列表中时,您实际上正在运行它们,然后将每个运行程序的结果作为多个进程并行运行

您要做的是将函数添加到
运行程序列表中,而不执行它们,然后在多处理
池中执行它们。实现这一点的方法是添加函数引用,即函数的名称。要做到这一点,您不应该包括paranthese,因为这是调用函数的语法,而不仅仅是命名函数

此外,为了让future异步执行,不可能直接调用
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
提交给执行器时调用运行程序。当结果准备就绪时,调用回调函数,将结果打印到屏幕。

请显示测试代码。任务管理器中可以将多个进程组合在一起,因此请确保您不会错过这些进程。@JohanL添加了编辑1,包括我的comcurrent.FutureSpliese试用版。请显示测试中的代码。任务管理器中可以将多个进程组合在一起,因此请确保您不会错过它们。@JohanL添加了编辑1,包括我的comcurrent.futuresWell试用版,因为OP完全控制Python代码,所以很有可能将其变成一个Python多处理程序。此外,即使没有此功能,也可以在一次Python调用中运行多个子流程。这是一种非常有效的方法,可以从Python内部协调流程,而不是直接在shell中或作为shell脚本。不确定“这不是一个单独的流程”是什么意思。。。Python的
子进程
模块用于生成新进程。您所做的区别是什么?好的,因为OP完全控制Python代码,所以很有可能将其变成单个Python多处理程序。此外,即使没有此功能,也可以在一次Python调用中运行多个子流程。这是一个非常有效的解释