如何在Python进程间传递对象而无需借助序列化?
实现Python主进程与后台进程无序列化传递对象的方案
针对你希望将序列化/反序列化操作从主进程转移到后台进程的需求,以下是几种可行的Python实现方式:
1. Unix系统专属:利用fork的写时复制特性
在Linux、macOS等Unix类系统中,Python的multiprocessing模块支持fork启动方式。当主进程通过fork创建后台进程时,子进程会完整继承主进程的内存空间(采用写时复制机制,仅当某一方修改内存时才会复制数据)。
- 实现逻辑:
- 主进程创建待传输的对象后,以
fork方式启动后台进程。 - 后台进程可直接访问主进程中的对象,执行序列化操作并处理网络传输。
- 接收端的后台进程完成反序列化后,同样通过
fork或共享内存将对象传递给主进程。
- 主进程创建待传输的对象后,以
- 优势:完全跳过主进程的序列化操作,零额外计算开销。
- 局限性:仅适用于Unix系统,Windows不支持
fork。
2. 跨平台方案:共享内存适配特定对象类型
对于数组、字节流等具有连续内存结构的对象,可通过共享内存实现无序列化传递:
- 使用
multiprocessing.shared_memory.SharedMemory创建共享内存区域,主进程将对象的原始二进制数据写入其中。 - 后台进程读取共享内存中的数据,直接重构对象(例如
numpy数组可从共享内存直接实例化),再执行网络传输所需的序列化。 - 对于自定义复杂对象,可拆解为基本类型字段写入共享内存,由后台进程重新组装。
- 优势:跨平台支持,避免主进程执行完整对象序列化。
- 局限性:需针对不同对象类型做适配,无法直接传递任意Python对象。
3. 第三方依赖方案:Apache Arrow Plasma内存存储
Apache Arrow的Plasma组件是一个高性能内存对象存储,可实现进程间高效共享对象:
- 主进程将对象写入Plasma存储,序列化操作由Plasma后台进程承担,主进程仅需发起写入请求。
- 后台进程从Plasma读取对象,执行网络传输的序列化逻辑。
- 接收端后台进程将数据写入Plasma,接收端主进程直接读取对象完成传递。
- 优势:跨平台支持,兼容大部分Python对象,主进程几乎无序列化开销。
- 局限性:需要额外部署Plasma服务,增加了项目依赖。
折中优化方案:主进程后台线程执行序列化
如果必须支持任意Python对象且跨平台,目前不存在完美的无序列化跨进程传递方案。此时可将序列化/反序列化操作放在主进程的独立后台线程中执行,而非主线程,这样不会阻塞用户的主进程业务逻辑,这也是你现有方案的低成本优化方向。同时可替换pickle为pyarrow、msgpack等更高效的序列化库,降低计算开销。
内容的提问来源于stack exchange,提问作者Yann Bouteiller
相关产品推荐
相关产品推荐

