我的程序有几个参数,其中一个名为challenges
,它从命令行接收整数值。我想通过将multiprocessing
的值传递给自定义方法challenges
来使用generation
:
import multiprocessing
gen = generator.GenParentClass()
mlp = multiprocessing.Pool(processes=multiprocessing.cpu_count())
X, y = mlp.imap_unordered(gen.generation, [args.challenges])
班级generation
中的方法GenParentClass
有这个简单的签名:
def generation(self, num):
#some stuff
然而,我收到此错误:
Traceback (most recent call last):
File "experiments.py", line 194, in <module>
X, y = mlp.imap_unordered(gen.generation, [args.challenges])
File "/anaconda/lib/python2.7/multiprocessing/pool.py", line 668, in next
raise value
cPickle.PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed
我不知道如何解决这个问题。一切似乎对我来说都是正确的!!任何帮助,谢谢。
答案 0 :(得分:1)
multiprocess
模块将pickles
的参数序列化(imap_unordered
)。似乎函数gen.generation
是一个实例方法(在类中定义),这意味着它不能被腌制,因此你的错误。
编辑:这是一个可能的解决方法,它定义了类之外的函数,并向该函数添加了其他参数,这些参数使用partial
中的itertools
填充:
import multiprocessing
from functools import partial
class GenParentClass(object):
a = None
b = None
def __init__(self, a, b):
self.a = a
self.b = b
# define this outside of GenParentClass (i.e., top level function)
def generation(num, x, y):
return x+y+num
gen = GenParentClass(3, 5)
mlp = multiprocessing.Pool(processes=multiprocessing.cpu_count())
R = mlp.imap_unordered(partial(generation, x=gen.a, y=gen.b), [1,2,3])
print([r for r in R]) # prints "[9, 10, 11]"
有关腌制能力的更多信息here。
有关functools的更多信息,请访问here。
编辑2:如果您使用multiprocess.Pool
且函数定义使用限定变量名self.a
和self.b
,则可以在不重写类外的函数的情况下执行此操作,但您赢了'能够检索输出,并且gen2的状态不会改变(完全没有调用函数的目的)。
gen2 = GenParentClass(4, 6)
p = {}
for key in range(5):
p[key] = multiprocessing.Process(target = GenParentClass.altgen, args = (gen2, key,))
p[key].start()
for key in p:
p[key].join()