Python3搁置用于多处理的项迭代器

问题描述 投票:0回答:1

我试图用multiprocessing.Pool分析一个大货架。使用只读模式它应该是线程安全的,但它接着首先读取一个大对象,然后通过池调度slowwwwly。这可以更有效地完成吗?

这是我正在做的最小例子。假设test_file.shelf已经存在并且很大(14GB +)。我可以看到这个剪辑拥抱20GB的RAM,但只有一小部分的搁架可以同时读取(比处理器更多的项目)。

from multiprocessing import Pool
import shelve

def func(key_val):
    print(key_val)

with shelve.open('test_file.shelf', flag='r') as shelf,\
     Pool(4) as pool:
    list(pool.imap_unordered(func, iter(shelf.items()))
python python-3.x iterator multiprocessing
1个回答
1
投票

货架本身不能快速打开,因为它们像对象一样工作,当你打开它们时,由于它在后端工作的方式,加载需要一些时间,特别是对于大型货架。为了使其像对象一样起作用,每次获得一个新项目时,该项目都会被加载到内存中的单独字典中。 lib reference

也来自docs

(imap)对于非常长的迭代,使用较大的chunksize值可以使作业完成比使用默认值1更快。

您使用的标准块大小为1,这导致需要很长时间才能通过非常大的搁置文件。文档建议分块而不是允许它一次发送1来加速它。

搁置模块不支持对搁置对象的并发读/写访问。 (多个同时读取访问是安全的。)当程序打开一个架子进行写入时,没有其他程序可以打开它进行读写。 Unix文件锁定可用于解决此问题,但这在Unix版本中有所不同,需要了解所使用的数据库实现。

最后,作为一个注释,我不确定您对多处理安全的假设是开箱即用的,具体取决于实现。

编辑:正如juanpa.arrivillaga所指出的那样,在this answer中它描述了后端发生了什么 - 你的整个可迭代可能正在被预先消耗,导致大量的内存使用。

© www.soinside.com 2019 - 2024. All rights reserved.