Sharing object (class instance) using multiprocessing Managers

SagittariusA picture SagittariusA · Aug 14, 2012 · Viewed 11.6k times · Source

I need to share an object and its methods between several processes in python. I am trying to use managers (in module multiprocessing) but it crashes. Here is a silly example of producer-consumer where the shared object between the two processes is just a list of numbers with four methods.

from multiprocessing import Process, Condition, Lock  
from multiprocessing.managers import BaseManager  
import time, os  
  
lock = Lock()  
waitC = Condition(lock)  
waitP = Condition(lock)  
  
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  
  
numManager.register('numeri', numeri, exposed = ['getLen', 'appendi', 'svuota', 'stampa'])  
  
def consume(waitC, waitP, listaNumeri):  
    lock.acquire()  
    if (listaNumeri.getLen() == 0):  
        waitC.wait()  
    listaNumeri.stampa()  
    listaNumeri.svuota()  
    waitP.notify()  
    lock.release()  
      
def produce(waitC, waitP, listaNumeri):  
    lock.acquire()  
    if (listaNumeri.getLen() > 0):  
        waitP.wait()  
    for i in range(10):  
        listaNumeri.appendi(i)  
    waitC.notify()  
    lock.release()  
  
      
def main():  
    mymanager = numManager()  
    mymanager.start()  
    listaNumeri = mymanager.numeri()  
    producer = Process(target = produce, args =(waitC, waitP, listaNumeri,))  
    producer.start()  
    time.sleep(2)  
    consumer = Process(target = consume, args =(waitC, waitP, listaNumeri,))  
    consumer.start()  
  
main() 

Anyway it always crashes like that, telling me this:

Process Process-3:
Traceback (most recent call last):
  File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
  File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
  File "./trySemProc.py", line 61, in consume
    if (listaNumeri.getLen() == 0):
  File "<string>", line 2, in getLen
  File "/usr/lib/python2.7/multiprocessing/managers.py", line 755, in _callmethod
    self._connect()
  File "/usr/lib/python2.7/multiprocessing/managers.py", line 742, in _connect
    conn = self._Client(self._token.address, authkey=self._authkey)
  File "/usr/lib/python2.7/multiprocessing/connection.py", line 169, in Client
    c = SocketClient(address)
  File "/usr/lib/python2.7/multiprocessing/connection.py", line 293, in SocketClient
    s.connect(address)
  File "/usr/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 2] No such file or directory

So what's the matter? How should I use these managers to share objects and their methods?

Answer

Rostyslav Dzinko picture Rostyslav Dzinko · Aug 14, 2012

You must join your processes to prevent main process exiting before child processes continue their execution. So add joins to your code:

 consumer.join()
 producer.join()

after you called start() methods of your processes.