util.py
def exec_multiprocessing(self, method, args):
with concurrent.futures.ProcessPoolExecutor() as executor:
results = pool.map(method, args)
return results
clone.py
def clone_vm(self, name, first_run, host, ip):
# clone stuff
invoke.py
exec_args = [(name, first_run, host, ip) for host, ip in zip(hosts, ips)]
results = self.util.exec_multiprocessing(self.clone.clone_vm, exec_args)
上面的代码给出了酸洗错误。我发现这是因为我们正在传递实例方法。因此,我们应该解开实例方法。但是我无法使其工作。
注意:我无法创建顶级方法来避免这种情况。我必须使用实例方法。
最佳答案
让我们从概述开始-为什么首先出现错误:multiprocessing
必须要求对数据进行腌制(序列化),以使它们沿着进程或线程传递。具体来说,pool
方法本身依赖于较低级别的queue
来堆叠任务并将其传递给线程/进程,并且queue
要求通过它的所有内容都必须是可选取的。
问题是,并非所有项目都是可拣选的-list of pickables-当人们尝试腌制一个不可腌制的对象时,会收到 PicklingError
异常(exception)-正是在您的情况下发生的情况,您传递了一个不可腌制的实例方法。
可能有多种解决方法(每个问题都是这种情况)-对我有用的解决方案是here by Dano-使pickle
处理这些方法并将其注册到 copy_reg
。
在模块clone.py
的开头添加以下行,以使clone_vm
可腌制(执行import
copy_reg
和types
):
def _pickle_method(m):
if m.im_self is None:
return getattr, (m.im_class, m.im_func.func_name)
else:
return getattr, (m.im_self, m.im_func.func_name)
copy_reg.pickle(types.MethodType, _pickle_method)
其他有用的答案-Alex Martelli,mrule,unutbu
关于python - PicklingError : Can't pickle <type 'function' > with python process pool executor,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31971180/