Python的multiprocessing.connection是否序列化?

2 投票
2 回答
2136 浏览
提问于 2025-04-17 08:25

Python的 multiprocessing.connection 让你可以使用监听者-客户端的模式。你可以选择它使用的套接字类型:

  • TCP套接字
  • Unix域套接字
  • Windows命名管道

那么,connection 在所有套接字类型中都要把消息进行序列化(也就是把数据转换成可以传输的格式)吗?还是后两种方式通过发送原生的Python对象来节省时间和CPU资源呢?

2 个回答

2

某种形式的序列化是必要的;不同的进程不能直接共享Python对象。

16.6.2.4. 连接对象

连接对象可以用来发送和接收可以被“打包”的对象或字符串。你可以把它们想象成一种面向消息的连接套接字。

3

所有可以被 multiprocessing.Connection 使用的传输通道(比如不同类型的套接字和管道)都是以流的方式工作的。因此,Python 对象必须被序列化/反序列化(或者说编码/解码也可以)才能通过这些通道进行传输和接收。

在 multiprocessing 模块中,所有连接类型都共享 _ConnectionBase 的方法,这个方法实现了 recv()send(obj)

def send(self, obj):
    """Send a (picklable) object"""
    self._check_closed()
    self._check_writable()
    buf = io.BytesIO()
    ForkingPickler(buf, pickle.HIGHEST_PROTOCOL).dump(obj)
    self._send_bytes(buf.getbuffer())

def recv(self):
    """Receive a (picklable) object"""
    self._check_closed()
    self._check_readable()
    buf = self._recv_bytes()
    return pickle.loads(buf.getbuffer())

在这里,我们看到所有的 Python 对象在传输之前会通过 pickle 使用一种二进制协议进行序列化,接收到后再进行反序列化。实际的发送和接收是通过 _send_bytes_recv_bytes 方法来完成的,这些方法对于每种传输通道的实现方式是不同的。

参考资料: https://github.com/schmir/python/blob/master/Lib/multiprocessing/connection.py

撰写回答