Python的multiprocessing.connection是否序列化?
Python的 multiprocessing.connection
让你可以使用监听者-客户端的模式。你可以选择它使用的套接字类型:
- TCP套接字
- Unix域套接字
- Windows命名管道
那么,connection
在所有套接字类型中都要把消息进行序列化(也就是把数据转换成可以传输的格式)吗?还是后两种方式通过发送原生的Python对象来节省时间和CPU资源呢?
2 个回答
2
某种形式的序列化是必要的;不同的进程不能直接共享Python对象。
连接对象可以用来发送和接收可以被“打包”的对象或字符串。你可以把它们想象成一种面向消息的连接套接字。
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