Python 我可以将子进程映射到主进程运行的同一个多处理池吗?
我对python3中的Python 我可以将子进程映射到主进程运行的同一个多处理池吗?,python,python-3.x,multiprocessing,python-multiprocessing,pool,Python,Python 3.x,Multiprocessing,Python Multiprocessing,Pool,我对python3中的多处理世界相对较新,因此,如果以前有人问过这个问题,我很抱歉。我有一个脚本,它从N个元素的列表中,对每个元素运行整个分析,将每个元素映射到不同的进程 我知道这是次优的,事实上我想提高多处理效率。我使用map()将每个进程运行到池()中,该池可以包含用户通过命令行参数指定的任意多个进程 下面是代码的外观: max_processes = 7 # it is passed by command line actually but not relevant here def
多处理
世界相对较新,因此,如果以前有人问过这个问题,我很抱歉。我有一个脚本,它从N个元素的列表中,对每个元素运行整个分析,将每个元素映射到不同的进程
我知道这是次优的,事实上我想提高多处理效率。我使用map()
将每个进程运行到池()
中,该池可以包含用户通过命令行参数指定的任意多个进程
下面是代码的外观:
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_函数都是可多处理的。我可以将这些子功能中的流程映射到主流程运行的同一池吗?不,您不能。该池(几乎)在辅助进程中不可用。这在一定程度上取决于游泳池使用的水 繁殖
启动一个新的Python解释器进程并导入模块。由于在该过程中,
\uuuu name\uuuuuuuuu
是'\uuuump\u main\uuuuuuu'
,因此不会执行\uuu name\uuuuuuuuu=='\uuuuuuuu main\uuuuuuuuuu'
块中的代码,并且worker中不存在池对象
叉子父进程的内存空间被复制到子进程的内存空间中。这将有效地导致每个辅助进程的内存空间中存在一个
池对象。
但是,该池无法使用。工作线程是在执行池的\uuuu init\uuu
过程中创建的,因此当工作线程被分叉时,池的初始化是不完整的。辅助进程中的池副本没有运行管理辅助进程、任务和结果的线程。无论如何,线程不会通过fork
进入子进程
此外,由于辅助对象是在初始化过程中创建的,因此此时池对象尚未指定给任何名称。虽然它确实潜伏在工作者的内存空间中,但它没有句柄。它不显示通过;我只是通过:
无论如何,该池对象是主进程中对象的副本
forkserver
我无法测试这个启动方法
为了解决您的问题,您可以在主进程中摆弄队列和队列处理程序线程,以便将工作人员的任务发回并委托给池,但我能想到的所有方法似乎都相当笨拙。
如果您努力将代码用于池中的处理,您很可能会得到更多可维护的代码
顺便说一句:我不确定允许用户通过命令行传递工人数量是否是个好主意。我建议至少给该值一个上边界via。不确定我是否得到了这个值。您希望在池的工作进程中运行main\u函数
,并且,在执行main\u函数
的进程中,您希望将sub\u函数*
提交到同一池中。这主要是因为大多数情况下,一个流程比其他流程持续的时间更长(需要在其中处理的数据更多),所以我希望充分利用剩余的流程来更快地完成它。我可以重新编码这件事,以避免这样做,但我很遗憾没有足够的时间,所以我正在寻找这种解决方法。谢谢你的详细回答。事实上,在代码中,我将min(args.processs,os.cpu_count())
作为工作进程数,因此如果用户在一个具有32个cpu的节点中指定80个工作进程,实际上只会使用32个。