multiprocessing - dzielenie złożonego obiektu
Mam dużądict
podobny do obiektu, który musi być współdzielony przez wiele procesów roboczych. Każdy pracownik odczytuje losowy podzbiór informacji w obiekcie i wykonuje z nim pewne obliczenia. Chciałbym uniknąć kopiowania dużego obiektu, ponieważ w urządzeniu szybko zabraknie pamięci.
Bawiłem się kodemto pytanie TAK i zmodyfikowałem to trochę, aby użyć puli procesów o stałym rozmiarze, która lepiej pasuje do mojego przypadku użycia. To jednak wydaje się go łamać.
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()
Wyjście jest
4315705168
------------ Process
producing 4315705168
producing 4315705168
producing 4315705168
producing 4315705168
producing 4315705168
--------------- Pool
producing 4299771152
producing 4315861712
producing 4299771152
producing 4315861712
producing 4299771152
Jak widać, w pierwszym przypadku wszystkie procesy robocze otrzymują ten sam obiekt (według identyfikatora). W drugim przypadku id nie jest taki sam. Czy to oznacza, że obiekt jest kopiowany?
P.S. Myślę, że to nie ma znaczenia, ale używamjoblib
, który wewnętrznie używałPool
:
from joblib import delayed, Parallel
print '------------- Joblib'
Parallel(n_jobs=4)(delayed(produce)(listaNumeri) for i in range(5))
które wyjścia:
------------- Joblib
producing 4315862096
producing 4315862288
producing 4315862480
producing 4315862672
producing 4315862352