【问题标题】:Why does python multiprocessing pickle objects to pass objects between processes?为什么 python 多处理泡菜对象在进程之间传递对象?
【发布时间】:2014-08-25 03:42:10
【问题描述】:

为什么 multiprocessing 包为 python pickle 对象在进程之间传递它们,即将不同进程的结果返回到主解释器进程?这可能是一个非常幼稚的问题,但是为什么进程 A 不能说处理 B “对象 x 在内存中的 y 点,它现在是你的了”,而不必执行将对象表示为字符串所需的操作。

【问题讨论】:

  • 进程不允许访问其他进程的内存。这有明显的安全原因,但也有可能一个进程搞砸并破坏其他一些(可能是关键的)进程的内存。

标签: python multiprocessing pickle


【解决方案1】:

multiprocessing 在不同的进程中运行作业。进程有自己独立的内存空间,一般不能通过内存共享数据。

要让进程进行通信,您需要某种渠道。一个可能的通道是“共享内存段”,这几乎就是它听起来的样子。但更常见的是使用“序列化”。我没有广泛研究这个问题,但我的猜测是共享内存解决方案耦合得太紧了;序列化允许进程进行通信,而不会让一个进程导致另一个进程出现故障。

当数据集非常大并且速度很关键时,共享内存段可能是最好的选择。我能想到的主要示例是视频帧缓冲区图像数据(例如,从用户模式驱动程序传递到内核,反之亦然)。

http://en.wikipedia.org/wiki/Shared_memory

http://en.wikipedia.org/wiki/Serialization

Linux 和其他 *NIX 操作系统提供了一种通过序列化共享数据的内置机制:“域套接字”这应该很快。

http://en.wikipedia.org/wiki/Unix_domain_socket

由于 Python 有 pickle 可以很好地用于序列化,multiprocessing 使用它。 pickle 是一种快速的二进制格式;一般来说,它应该比 XML 或 JSON 之类的序列化格式更有效。还有其他二进制序列化格式,例如 Google Protocol Buffers。

使用序列化的一个好处是:在一台计算机内共享工作(使用额外的内核)或在多台计算机之间共享工作(使用集群中的多台计算机)几乎相同。序列化工作是相同的,网络套接字的工作方式类似于域套接字。

编辑:@Mike McKerns 在下面的评论中说,multiprocessing 有时可以使用共享内存。我做了一个谷歌搜索,发现了这个很棒的讨论:Python multiprocessing shared memory

【讨论】:

  • 要使用共享内存,multiprocessing 可以利用ctypes 库——并且旨在共享Pool(4).map(f, x) 中的x。你仍然需要将f 传递给其他带有pickle 的处理器。
  • @MikeMcKerns 谢谢你。我已经更新了答案以包含更多信息。我不记得multiprocessing 可以使用共享内存。 (不过我应该猜到了。有时数据量很大,Python 应该能够应付。)
猜你喜欢
  • 2014-10-12
  • 2015-03-08
  • 2017-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多