Python多处理指南似乎有冲突:共享内存或泡菜?

时间:2018-06-04 20:10:53

标签: python multiprocessing fork

我正在使用Python multiprocessing模块来在多个进程之间共享一个(只读)数组。我的目标是使用multiprocessing.Array分配数据,然后让我的代码 forked forkserver),这样每个工作人员都可以直接从数组中读取它们的工作。< / p>

在阅读Programming guidelines时,我有点困惑。

首先说:

  

避免共享状态

     

应尽量避免大量移动      流程之间的数据。

     

最好坚持使用队列或管道      进程之间的通信而不是使用较低级别      同步原语。

然后,下面几行:

  

最好继承而不是pickle / unpickle

     

使用spawn或forkserver时启动方法的方法很多      多处理需要是可选择的,以便子进程可以使用      他们。但是,通常应该避免发送共享对象      使用管道或队列的其他进程。相反,你应该安排      程序,以便需要访问共享资源的进程      在别处创建的可以从祖先进程继承它。

据我了解,队列管道 pickle对象。如果是这样,这两个指南是不是冲突了?

感谢。

1 个答案:

答案 0 :(得分:1)

第二指南是与您的用例相关的指南。

首先提醒您,这不是线程,您可以使用锁(或原子操作)操作共享数据结构。如果对所有内容使用Manager.dict()(实际上是SyncManager.dict),则每次读写都必须访问管理器的进程,并且还需要线程程序的典型同步(本身可能从跨过程中获得更高的成本。)

第二条准则建议通过fork继承共享的只读对象;在 forkserver 的情况下,这意味着您必须在调用set_start_method之前创建此类对象,因为所有工作者都是当时创建的进程的子级。

有关此类共享的可用性的报告是mixed at best,但是如果您可以使用任何C类数组类型的小数(例如numpy或标准array模块),您应该看到良好的性能(因为大多数页面永远不会被写入来处理引用计数)。请注意,您在此处需要multiprocessing.Array(尽管它可能正常工作),因为您不需要在一个并发进程中写入在另一个进程中可见。