python3 进程间共享列表对象
python3 shared list object among processes
我想在进程池中的进程之间共享一个大对象(这是一个str列表的列表)。该对象是只读的,所以我不想锁定它。
我试过了multiprocessing.Value,不过好像只支持ctypes,不过我想分享一个str的list.
我也试过multiprocessing.Manager.list,但是根据文档,管理器是一个同步管理器,我想它会锁定它,这不是我想要的。
那么执行此操作的最佳做法是什么?
这取决于你愿意做出什么样的权衡。
我可以看到多种方法,各有优缺点:
- 创建匿名
mmap
. These are specifically designed to be shared between processes created with multiprocessing
or os.fork()
. They have low overhead and translate almost directly into operating system primitives for shared memory. The downside is that you just get one huge fixed-length array of bytes. If you want additional structure on top of that (for example, a list of lists of strings), you need to manually serialize and deserialize it. You may find the struct
and array
modules helpful for that purpose. If you're feeling adventurous, you can also access the elements in-place through a memoryview
object.
- 不要共享列表。子进程已经继承了父进程内存中任何内容的副本。由于列表是 read-only,这可能会影响性能,但不会产生不正确的结果。理论上,现代操作系统
fork()
的 copy-on-write 设计应该可以减轻这些性能影响。实际上,这对我们没有任何作用,因为 Python reference-counts 字符串写入内存并强制 OS 复制附近的数据。 array
不会重新计算其内容,因此如果您的单个数组足够大,则可能不太容易受到此问题的影响。
- 用
tempfile
and store the information there using json
, pickle
, or sqlite3
创建一个临时文件。我们可以假设临时文件对子进程也是可见的,并且 tempfile
模块会在完成后为您清理它。但是,从永久存储读取数据通常比 in-memory 解决方案慢。
我想在进程池中的进程之间共享一个大对象(这是一个str列表的列表)。该对象是只读的,所以我不想锁定它。 我试过了multiprocessing.Value,不过好像只支持ctypes,不过我想分享一个str的list.
我也试过multiprocessing.Manager.list,但是根据文档,管理器是一个同步管理器,我想它会锁定它,这不是我想要的。
那么执行此操作的最佳做法是什么?
这取决于你愿意做出什么样的权衡。
我可以看到多种方法,各有优缺点:
- 创建匿名
mmap
. These are specifically designed to be shared between processes created withmultiprocessing
oros.fork()
. They have low overhead and translate almost directly into operating system primitives for shared memory. The downside is that you just get one huge fixed-length array of bytes. If you want additional structure on top of that (for example, a list of lists of strings), you need to manually serialize and deserialize it. You may find thestruct
andarray
modules helpful for that purpose. If you're feeling adventurous, you can also access the elements in-place through amemoryview
object. - 不要共享列表。子进程已经继承了父进程内存中任何内容的副本。由于列表是 read-only,这可能会影响性能,但不会产生不正确的结果。理论上,现代操作系统
fork()
的 copy-on-write 设计应该可以减轻这些性能影响。实际上,这对我们没有任何作用,因为 Python reference-counts 字符串写入内存并强制 OS 复制附近的数据。array
不会重新计算其内容,因此如果您的单个数组足够大,则可能不太容易受到此问题的影响。 - 用
tempfile
and store the information there usingjson
,pickle
, orsqlite3
创建一个临时文件。我们可以假设临时文件对子进程也是可见的,并且tempfile
模块会在完成后为您清理它。但是,从永久存储读取数据通常比 in-memory 解决方案慢。