¿Cómo cambiar el método de serialización utilizado por el multiprocesamiento de Python?

¿Cómo puedo cambiar el método de serialización utilizado por la biblioteca de multiprocessing Python? En particular, el método de serialización predeterminado utiliza la biblioteca pickle con la versión del protocolo pickle predeterminado para esa versión de Python. El protocolo de pickle predeterminado es la versión 2 en Python 2.7 y la versión 3 en Python 3.6. ¿Cómo puedo configurar la versión del protocolo en 2 en Python 3.6, por lo que puedo usar algunas de las clases (como Client y Listener ) en la biblioteca de multiprocessing para comunicarme entre un procesamiento de servidor ejecutado por Python 2.7 y un proceso de cliente ejecutado por Python 3.6?

(Nota: como prueba, modifiqué la línea 206 de multiprocessing/connection.py agregando protocol=2 a la llamada dump() para forzar la versión del protocolo a 2 y mis procesos cliente / servidor trabajaron en mis pruebas limitadas con el servidor ejecutado por 2.7 y el cliente por 3.6).

En Python 3.6, se fusionó un parche para permitir que se configurara el serializador, pero el parche no estaba documentado, y no he descubierto cómo usarlo. Aquí es cómo traté de usarlo (también publiqué esto en el ticket de Python al que hice el enlace):

pickle2reducer.py:

 from multiprocessing.reduction import ForkingPickler, AbstractReducer class ForkingPickler2(ForkingPickler): def __init__(self, *args): if len(args) > 1: args[1] = 2 else: args.append(2) super().__init__(*args) @classmethod def dumps(cls, obj, protocol=2): return ForkingPickler.dumps(obj, protocol) def dump(obj, file, protocol=2): ForkingPickler2(file, protocol).dump(obj) class Pickle2Reducer(AbstractReducer): ForkingPickler = ForkingPickler2 register = ForkingPickler2.register dump = dump 

y en mi cliente:

 import pickle2reducer multiprocessing.reducer = pickle2reducer.Pickle2Reducer() 

en la parte superior antes de hacer cualquier otra cosa con multiprocessing . Sigo viendo ValueError: unsupported pickle protocol: 3 en el servidor ejecutado por Python 2.7 cuando hago esto.

Creo que el parche al que te refieres funciona si estás usando un objeto de “contexto” de multiprocesamiento.

Usando su pickle2reducer.py, su cliente debe comenzar con:

 import pickle2reducer import multiprocessing as mp ctx = mp.get_context() ctx.reducer = pickle2reducer.Pickle2Reducer() 

Y ctx tiene la misma API que multiprocessing .

¡Espero que ayude!