【发布时间】:2014-01-24 04:39:51
【问题描述】:
我有一个类似dict 的大型对象,需要在多个工作进程之间共享。每个工作人员读取对象中信息的随机子集并对其进行一些计算。我想避免复制大对象,因为我的机器很快就会耗尽内存。
我正在使用this SO question 的代码,并对其进行了一些修改以使用固定大小的进程池,这更适合我的用例。然而,这似乎打破了它。
from multiprocessing import Process, Pool
from multiprocessing.managers import BaseManager
class numeri(object):
def __init__(self):
self.nl = []
def getLen(self):
return len(self.nl)
def stampa(self):
print self.nl
def appendi(self, x):
self.nl.append(x)
def svuota(self):
for i in range(len(self.nl)):
del self.nl[0]
class numManager(BaseManager):
pass
def produce(listaNumeri):
print 'producing', id(listaNumeri)
return id(listaNumeri)
def main():
numManager.register('numeri', numeri, exposed=['getLen', 'appendi',
'svuota', 'stampa'])
mymanager = numManager()
mymanager.start()
listaNumeri = mymanager.numeri()
print id(listaNumeri)
print '------------ Process'
for i in range(5):
producer = Process(target=produce, args=(listaNumeri,))
producer.start()
producer.join()
print '--------------- Pool'
pool = Pool(processes=1)
for i in range(5):
pool.apply_async(produce, args=(listaNumeri,)).get()
if __name__ == '__main__':
main()
输出是
4315705168
------------ Process
producing 4315705168
producing 4315705168
producing 4315705168
producing 4315705168
producing 4315705168
--------------- Pool
producing 4299771152
producing 4315861712
producing 4299771152
producing 4315861712
producing 4299771152
如您所见,在第一种情况下,所有工作进程都获得相同的对象(通过 id)。第二种情况,id不一样。这是否意味着正在复制对象?
附:我认为这并不重要,但我使用的是joblib,它在内部使用了Pool:
from joblib import delayed, Parallel
print '------------- Joblib'
Parallel(n_jobs=4)(delayed(produce)(listaNumeri) for i in range(5))
哪个输出:
------------- Joblib
producing 4315862096
producing 4315862288
producing 4315862480
producing 4315862672
producing 4315862352
【问题讨论】:
-
检查zeromq.org,它以简单的方式在进程之间共享信息。
标签: python concurrency multiprocessing