为什么Python多进程需要通过pickle在进程间传递对象?

11 投票
1 回答
4912 浏览
提问于 2025-04-18 12:03

为什么Python的multiprocessing这个模块要把pickle对象进行处理,以便在不同的进程之间传递,也就是说,把不同进程的结果返回给主程序?这个问题可能听起来很简单,但我想知道,为什么进程A不能直接告诉进程B“对象x在内存的y位置,现在是你的了”,而非得把这个对象转换成字符串的形式呢?

1 个回答

7

multiprocessing 是一个可以让程序同时运行多个任务的工具。每个任务在不同的进程中运行,这些进程有各自独立的内存空间,通常情况下,它们不能通过内存直接共享数据。

为了让这些进程之间能够沟通,你需要一种渠道。一个可能的渠道是“共享内存段”,这听起来就是字面意思。但更常用的方式是“序列化”。我没有深入研究这个问题,但我猜共享内存的解决方案可能太紧密了;而序列化则允许进程之间沟通,而不会让一个进程影响到另一个进程。

当数据集非常大,且速度很重要时,共享内存段可能是最好的选择。我能想到的主要例子是视频帧缓冲图像数据(比如,从用户模式驱动程序传递到内核,或者反过来)。

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

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

Linux和其他类Unix操作系统提供了一种内置机制,可以通过序列化来共享数据:即“域套接字”。这应该是相当快速的。

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

由于Python有一个叫pickle的工具,适合用于序列化,所以multiprocessing也使用它。pickle是一种快速的二进制格式;一般来说,它比像XML或JSON这样的序列化格式更高效。还有其他的二进制序列化格式,比如Google的协议缓冲区。

使用序列化的一个好处是:在一台电脑内部共享工作(利用额外的核心)和在多台电脑之间共享工作(利用集群中的多台电脑)几乎是一样的。序列化的工作是相同的,网络套接字的工作方式也和域套接字差不多。

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

撰写回答