import multiprocessing
class multiprocessing_issue:
def __init__(self):
self.test_mp()
def print_test(self):
print "TEST TEST TEST"
def test_mp(self):
p = multiprocessing.Pool(processes=4)
p.apply_async(self.print_test, args=())
print "finished"
if __name__ == '__main__':
multiprocessing_issue()
我已经在上面设置了一个简单的测试,创建一个类,调用apply_async
,其功能应打印"TEST TEST TEST"
。当我运行此功能时,我会看到"finished"
打印,但它永远不会像预期的那样打印"TEST TEST TEST"
。
任何人都可以在这个简单的测试案例中看到错误吗?我已经设置了它以复制我在代码中使用它的方式。
python 2.7在ubuntu
修改test_mp
如下:
def test_mp(self):
p = multiprocessing.Pool(processes=4)
r = p.apply_async(self.print_test, args=())
print r.get()
答案将更加清楚。
Traceback (most recent call last):
File "test.py", line 18, in <module>
multiprocessing_issue()
File "test.py", line 6, in __init__
self.test_mp()
File "test.py", line 14, in test_mp
print r.get()
File "/usr/lib/python2.7/multiprocessing/pool.py", line 567, in get
raise self._value
cPickle.PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed
实例方法不能轻易序列化。Pickle协议序列化函数时的作用只是将其转换为字符串。
In [1]: dumps(function)
Out[1]: 'c__main__nfunctionnp0n.'
对于子过程,很难找到您实例方法所指的正确对象,这是由于单独的过程地址空间。
莳萝等模块比泡菜做得更好。但是,由于逻辑很容易变得混乱,我会阻止您混合并发和OOP。
ah,如果我在模块级别定义方法而不是类级别的方法,这是一个问题,这是一个问题。
import multiprocessing
class multiprocessing_issue:
def __init__(self):
self.test_mp()
def test_mp(self):
p = multiprocessing.Pool(4)
r = p.apply_async(mptest, args=())
r.get()
print "finished"
def mptest():
print "TEST TEST TEST"
if __name__ == '__main__':
multiprocessing_issue()