为什么Python多进程会使用pickle对象来在进程间传递对象?

11
为什么 Python 的 multiprocessing 包使用 pickle 对象在进程间传递,例如将不同进程的结果返回到主解释器进程?这可能是一个非常天真的问题,但为什么进程 A 不能告诉进程 B:“内存中的对象 x 在 y 点,现在它是你的了”,而不必执行表示对象为字符串所需的操作呢?

1
进程不允许访问其他进程的内存。这其中有明显的安全原因,同时也存在一个进程出错并破坏某些其他(可能是关键性)进程的内存的可能性。 - dano
1个回答

7

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。但你仍然需要使用 picklef 传递给其他处理器。 - Mike McKerns
@MikeMcKerns 谢谢您的帮助。我已经更新了答案,加入了更多信息。我之前没有想到multiprocessing可以使用共享内存。(不过我应该猜到的。有时候数据很大,Python也应该能够处理。) - steveha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接