【问题标题】:Can I map a subprocess to the same multiprocessing.Pool where the main process is running?我可以将子进程映射到主进程运行的同一个 multiprocessing.Pool 吗?
【发布时间】:2019-07-02 09:58:34
【问题描述】:

我对 python3 中的multiprocessing 世界比较陌生,因此如果之前有人问过这个问题,我很抱歉。我有一个脚本,它从 N 个元素的列表中对每个元素运行整个分析,将每个元素映射到不同的进程。

我知道这是次优的,实际上我想提高多处理效率。我使用map() 将每个进程运行到Pool() 中,该Pool() 可以包含用户通过命令行参数指定的尽可能多的进程。

代码如下所示:

max_processes = 7 
# it is passed by command line actually but not relevant here

def main_function( ... ):

    res_1 = sub_function_1( ... )
    res_2 = sub_function_2( ... )

if __name__ == '__main__':

    p = Pool(max_processes)
    Arguments = []

    for x in Paths.keys():
        # generation of the arguments
        ... 
        Arguments.append( Tup_of_arguments )

    p.map(main_function, Arguments)

    p.close()
    p.join()

如您所见,我的进程调用了一个主函数,而该主函数又一个接一个地调用了许多其他函数。现在,每个 sub_functions 都是可多处理的。我可以从那些映射到主进程运行的同一个池的子函数中映射进程吗?

【问题讨论】:

  • 不确定我是否得到了这个。您想在您的池p 的工作人员中运行main_function,并且在执行main_function 的进程中,您想将sub_function_* 提交到同一个池?
  • 没错。这主要是因为大多数时候一个进程比其他进程持续的时间长得多(其中要处理的数据更多),所以我想充分利用剩余的进程来更快地完成它。我可以重新编码整个事情以避免这样做,但遗憾的是我没有足够的时间,所以我正在寻找这种解决方法。

标签: python python-3.x multiprocessing python-multiprocessing pool


【解决方案1】:

不,你不能。
该池(几乎)在工作进程中不可用。这在一定程度上取决于用于池的start method

生成
启动一个新的 Python 解释器进程并导入该模块。由于在该进程中__name__'__mp_main__',因此不会执行__name__ == '__main__' 块中的代码,并且worker 中不存在池对象。

分叉
父进程的内存空间被复制到子进程的内存空间中。这有效地导致每个工作人员的内存空间中存在一个现有的Pool 对象。
但是,该池无法使用。工人是在池的__init__ 执行期间创建的,因此当工人分叉时,池的初始化是不完整的。工作进程中的池副本没有运行管理工作人员、任务和结果的线程。无论如何,线程都不会通过fork 进入子进程。
此外,由于工作人员是在初始化期间创建的,因此池对象此时尚未分配给任何名称。虽然它确实潜伏在工人的内存空间中,但没有处理它。它不会通过globals() 显示;我只通过gc.get_objects()找到它:<multiprocessing.pool.Pool object at 0x7f75d8e50048>
无论如何,该池对象是主进程中的对象的副本

分叉服务器
我无法测试这个启动方法

为了解决您的问题,您可以在主进程中摆弄队列和队列处理程序线程,以将工作人员的任务发回并将它们委托给池,但我能想到的所有方法看起来很笨拙。
如果您努力采用它在池中进行处理,您很可能最终会得到更多可维护的代码。

顺便说一句:我不确定允许用户通过命令行传递工作人员的数量是否是个好主意。我建议至少通过os.cpu_count() 为该值设置一个上限。

【讨论】:

  • 感谢您的详细回答。事实上,在代码中我将min(args.processes, os.cpu_count())作为worker的数量,所以如果用户在一个拥有32个CPU的节点中指定80个worker,实际上只会使用32个。
猜你喜欢
  • 1970-01-01
  • 2017-08-07
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 2019-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多