Python 使用 pickle、kwargs 和函数引用进行多处理
Python multiprocessing using pickle, kwargs, and function references
我在 python 中使用任何有效的多处理框架时遇到问题(无论是 scoop 还是多处理)。
我有以下情况:
- 一个 class 'Foo' 拥有一个功能 'f'
- 第二个 class 'Bar' 获取参数 (kwargs) 并保存 class 'Foo' 的实例(包含函数)
- 在'Bar'中,class Foo的函数使用给定的参数执行。
- 出于统计意义的原因,结果是多次运行的平均值,在本例中为 10 次(未在给定示例中显示)。
示例如下:
import multiprocessing as mp
class Foo:
def __init__(self, f):
self.f = f
class Bar:
def __init__(self, foo, **kwargs):
self.args = kwargs
self.foo = foo
def execute(self):
pool = mp.Pool(5)
f = lambda x : self.foo.f(**x)
args = [self.args] * 10
results = pool.map(f, args)
if __name__ == '__main__':
def anything(**kwargs):
print(kwargs['z'])
return kwargs['x'] * kwargs['y']
foo = Foo(anything)
args = {'x':10, 'y':27, 'z':'Hello'}
bar = Bar(**args)
我知道函数必须在模块级别才能被选中。有什么方法可以使函数可选?不幸的是,我在 Python OOP 方面经验不多,所以我可能遗漏了一个重点!
谢谢!
编辑:
不幸的是,即使使用使用 dill 而不是 pickle 的模块 "multiprocess"(感谢 Mike McKerns),也不能保证我的问题得到解决。对于我的程序的一些短期运行,一切都很好。由于某些原因,当我收到以下错误时,多进程似乎会产生竞争条件:
Exception in thread Thread-3:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/local/lib/python2.7/dist-packages/multiprocess/pool.py", line 389, in _handle_results
task = get()
File "/usr/local/lib/python2.7/dist-packages/dill/dill.py", line 209, in loads
return load(file)
File "/usr/local/lib/python2.7/dist-packages/dill/dill.py", line 199, in load
obj = pik.load()
File "/usr/lib/python2.7/pickle.py", line 864, in load
dispatch[key](self)
File "/usr/lib/python2.7/pickle.py", line 1096, in load_global
klass = self.find_class(module, name)
File "/usr/local/lib/python2.7/dist-packages/dill/dill.py", line 353, in find_class
return StockUnpickler.find_class(self, module, name)
File "/usr/lib/python2.7/pickle.py", line 1132, in find_class
klass = getattr(mod, name)
AttributeError: 'module' object has no attribute 'Individual'
(个人是一个class,我的程序[使用deap的遗传算法])有什么想法吗?
(重复上面的评论)
将 multiprocess
包替换为 multiprocessing
,代码无需其他更改即可正常工作。这是因为 multiprocess
是 multiprocessing
的一个分支,它使用 dill
而不是 pickle
...在解释器会话中写入。这是对 multiprocessing
.
的分叉所做的唯一更改
见 and and 等
我在 python 中使用任何有效的多处理框架时遇到问题(无论是 scoop 还是多处理)。
我有以下情况:
- 一个 class 'Foo' 拥有一个功能 'f'
- 第二个 class 'Bar' 获取参数 (kwargs) 并保存 class 'Foo' 的实例(包含函数)
- 在'Bar'中,class Foo的函数使用给定的参数执行。
- 出于统计意义的原因,结果是多次运行的平均值,在本例中为 10 次(未在给定示例中显示)。
示例如下:
import multiprocessing as mp
class Foo:
def __init__(self, f):
self.f = f
class Bar:
def __init__(self, foo, **kwargs):
self.args = kwargs
self.foo = foo
def execute(self):
pool = mp.Pool(5)
f = lambda x : self.foo.f(**x)
args = [self.args] * 10
results = pool.map(f, args)
if __name__ == '__main__':
def anything(**kwargs):
print(kwargs['z'])
return kwargs['x'] * kwargs['y']
foo = Foo(anything)
args = {'x':10, 'y':27, 'z':'Hello'}
bar = Bar(**args)
我知道函数必须在模块级别才能被选中。有什么方法可以使函数可选?不幸的是,我在 Python OOP 方面经验不多,所以我可能遗漏了一个重点! 谢谢!
编辑: 不幸的是,即使使用使用 dill 而不是 pickle 的模块 "multiprocess"(感谢 Mike McKerns),也不能保证我的问题得到解决。对于我的程序的一些短期运行,一切都很好。由于某些原因,当我收到以下错误时,多进程似乎会产生竞争条件:
Exception in thread Thread-3:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/local/lib/python2.7/dist-packages/multiprocess/pool.py", line 389, in _handle_results
task = get()
File "/usr/local/lib/python2.7/dist-packages/dill/dill.py", line 209, in loads
return load(file)
File "/usr/local/lib/python2.7/dist-packages/dill/dill.py", line 199, in load
obj = pik.load()
File "/usr/lib/python2.7/pickle.py", line 864, in load
dispatch[key](self)
File "/usr/lib/python2.7/pickle.py", line 1096, in load_global
klass = self.find_class(module, name)
File "/usr/local/lib/python2.7/dist-packages/dill/dill.py", line 353, in find_class
return StockUnpickler.find_class(self, module, name)
File "/usr/lib/python2.7/pickle.py", line 1132, in find_class
klass = getattr(mod, name)
AttributeError: 'module' object has no attribute 'Individual'
(个人是一个class,我的程序[使用deap的遗传算法])有什么想法吗?
(重复上面的评论)
将 multiprocess
包替换为 multiprocessing
,代码无需其他更改即可正常工作。这是因为 multiprocess
是 multiprocessing
的一个分支,它使用 dill
而不是 pickle
...在解释器会话中写入。这是对 multiprocessing
.
见 and and 等