How do I create the python shared object of my class which can be modified by worker processes. I created the worker processes by using multiprocessing.Process module. I have some knowledge about multiprocessing.Manager module. Can any one explain with example how to register my class in to Manager, start the manager and create the shared object of my class.
Asked
Active
Viewed 6,919 times
1 Answers
6
Here is an example:
from multiprocessing import Process, Pool
from multiprocessing.managers import BaseManager
class MySharedClass(object):
stored_value = 0
def get(self):
return self.stored_value
def set(self, new_value):
self.stored_value = new_value
return self.stored_value
class MyManager(BaseManager):
pass
MyManager.register('MySharedClass', MySharedClass)
def worker ( proxy_object, i):
proxy_object.set( proxy_object.get() + i )
print ("id %d, sum %d" %(i, proxy_object.get()))
return proxy_object
if __name__ == '__main__':
manager = MyManager()
manager.start()
shared = manager.MySharedClass()
pool = Pool(5)
for i in range(33):
pool.apply(func=worker, args=(shared, i))
pool.close()
pool.join()
print "result: %d" % shared.get()
id 0, sum 0
id 1, sum 1
id 2, sum 3
...
id 31, sum 496
id 32, sum 528
result: 528
Another variant (have never use it in the real project):
from multiprocessing import Process, Pool
from multiprocessing.managers import BaseManager, NamespaceProxy
class MySharedClass(object):
def __init__(self):
self.stored_value = 0
def get(self):
return self.stored_value
def set(self, new_value):
self.stored_value = new_value
return self.stored_value
class MyManager(BaseManager):
pass
class MyProxy(NamespaceProxy):
_exposed_ = ('__getattribute__', '__setattr__', '__delattr__')# add 'get' to use get
#def get(self):
# callmethod = object.__getattribute__(self, '_callmethod')
# return callmethod('get')
MyManager.register('MySharedClass', MySharedClass, MyProxy)
def worker ( proxy_object, i):
proxy_object.stored_value = proxy_object.stored_value + i
print ("id %d, sum %d" %(i, proxy_object.stored_value))
return proxy_object
if __name__ == '__main__':
manager = MyManager()
manager.start()
shared = manager.MySharedClass()
print shared.stored_value
pool = Pool(5)
for i in range(33):
pool.apply(func=worker, args=(shared, i))
pool.close()
pool.join()
print "result: %d" % shared.stored_value

minskster
- 512
- 3
- 6
-
1if I put def __init__(self) method and put self.stored_value = 0 in it and trying to access this variable like proxy_object.stored_value += 1. Why It is giving the Error : AttributeError: 'AutoProxy[MySharedClass]' object has no attribute 'stored_value'. My point is if I create a same variable using multiprocessing Value() or Manager() class and share it; then we can access using object reference operator (.) . I want to access the object variables of MySharedClass() in worker process using object reference operator – Rahul.Shikhare Mar 01 '16 at 11:40
-
It would be nice to use @property and <>.setter decorators. But I have found only one way and have never use it before. It's NamespaceProxy. Don't know what kind of issues can be appeared. Look at the updated answer. – minskster Mar 01 '16 at 13:53
-
In the above solution if I am importing ' import eventlet' and calling 'eventlet.monkey_patch() ' It is giving the Error as : IOError: [Errno 11] Resource temporarily unavailable – Rahul.Shikhare Mar 02 '16 at 12:17
-
I have never used eventlet, will try as get a time, but I have an application with multiprocessing, gevent ( another concurrent networking library), flask and websocket. It was a problem to get it all workable together. I spent a lot of time to find compatible versions of all packages gevent, gevent-socketio, greenlet ... . – minskster Mar 03 '16 at 07:05