我想在进程池中的进程之间共享一个大对象(这是str列表的列表)。该对象是只读的,所以我不想锁定它。 我尝试过多处理。值,但似乎它只支持 ctypes,但我想分享一个 str 列表列表。
我也尝试过多处理。Manager.list,但根据文档,管理器是一个同步管理器,我想它会有一个锁,这不是我想要的。
那么,这样做的最佳实践是什么?
这取决于你愿意做出什么样的权衡。
我可以看到多种方法,有优点和缺点:
- 创建匿名
mmap
。 这些专门设计用于在使用multiprocessing
或os.fork()
创建的进程之间共享。 它们的开销很低,几乎直接转换为共享内存的操作系统基元。 缺点是你只得到一个巨大的固定长度的字节数组。 如果需要在此之上添加其他结构(例如,字符串列表列表),则需要手动序列化和反序列化它。 您可能会发现struct
和array
模块对此功能很有帮助。 如果您喜欢冒险,还可以通过memoryview
对象就地访问元素。 - 不要共享列表。 子进程已继承父进程内存中任何内容的副本。 由于列表是只读的,因此这可能会对性能产生影响,但不会产生不正确的结果。 从理论上讲,这些性能影响应该通过现代操作系统
fork()
的写入时复制设计来减轻。 实际上,这对我们没有任何作用,因为 Python 引用对字符串进行计数,这会写入内存并强制操作系统复制附近的数据。array
不会引用其内容,因此,如果单个数组足够大,则可能不太容易受到此问题的影响。 - 创建一个带有
tempfile
的临时文件,并使用json
、pickle
或sqlite3
将信息存储在其中。 我们可以假设临时文件对子进程也是可见的,tempfile
模块将在完成后为您清理它。 但是,从永久存储读取数据通常比内存中解决方案慢。