Python-将进程池与不可拾取的对象一起使用

时间:2019-12-26 13:26:20

标签: python parallel-processing multiprocessing

假设我有一个不能被腌制的对象,但是我在Linux上运行我的代码,并且想利用fork的优点。

如果我正在从解释器运行代码,则它看起来像这样:

from multiprocessing.pool import Pool

# large object that takes time to calculate - and is not picklable
large_obj = get_large_obj()

def some_func(c):
    return large_obj.do_something_with_int(c)

pool = Pool(64)
pool.map(some_func,[1,2,3,4,5,6,7,.....,10000])

如果我在Linux上运行它,它将起作用,因为所有过程都会“ 知道large_obj

我的问题是-如果我想在一个类内或仅在一个方法内使用此代码段,它将无法正常工作,因为它将使我的函数失效,因为它将是一个未绑定的方法。

我不想使用其他进程池库(比如loky),因为我的大对象是不可腌制的,即使使用cloudpickle也是如此(或dill

我不想为每个新进程重新计算大对象。我只想计算一次,然后在pool中使用它。

有什么解决办法吗?

1 个答案:

答案 0 :(得分:1)

简而言之,您已将 [TIME]的成本与[SPACE]的成本进行斗争(避免重复副本)。

与泡菜相关的阶段(这里是标准python方式的阻止者,如何进行过程实例化,本身并没有解决问题)在此全局视图中并不重要。

避免泡菜/复制只是意味着您必须为“ 共享 ”(不可复制)资源-{{1} }类包装器。

  

Q 有没有任何解决方案

是的

可能的解决方案之一可能是设计并开始运行足够智能的系统体系结构,其中large_obj只需计算一次,并且其包装类可以同时进行(不是真正的- large_obj操作)响应“ 远程”进程的请求(进程位于同一主机上或分布在全球范围内)。

为了实现这个目标,我将开始使用经过适当调整的ZeroMQ“中介”基础结构,其中所有[PARALLEL]传输类都可以并且可以共存于同一基础结构中,从而允许计算代理同时处于在紧密放置的区域内(在同一主机上,需要最大的接近度和最小的延迟)和/或跨互连的分布式代理的广泛网络(在远程主机上,其中性能扩展需要比单个本地主机更多的处理能力)平台可以提供)。

生成的架构将利用所需的{ inproc:// | ipc:// | tipc:// | tcp:// | norm:// | pgm:// | epgm:// | vmci:// }方式的“ 轻量”-装有ZeroMQ的进程(处理Agent),并在任何形式的同时并发- [SPACE](实际的硬件和/或网格计算资源仍在限制可能的true-Pool代码执行的范围,因此“ just ”-{{1} }在严格的计算机科学学科方面,代码执行更为合适。每个这样的流程实例都可以独立存在,并临时向“远程共享 -service-Agent”提交请求(该代理确实拥有[PARALLEL]的唯一一个实例) ,包括所有需要的方法,包括ZeroMQ通信处理工具,在这些方法中,来自远程代理的传入请求将得到有效的处理,而不会进行酸洗,并且不会过多[CONCURRENT]副本的内存转移,从而避免了任何形式的锁定和阻止(但仍然可以进行性能扩展和等待时间调整),并将“ 计算 ”答复(大小正确,小而有效的答复)返回给各自远程代理,根据需要)。