2016-03-01 3 views
2

Как создать общий объект python моего класса, который может быть изменен рабочими процессами. Я создал рабочие процессы, используя модуль multiprocessing.Process. У меня есть некоторые сведения о модуле multiprocessing.Manager. Может ли кто-нибудь объяснить, например, как зарегистрировать мой класс в Менеджере, запустить менеджера и создать общий объект моего класса.python Класс Объект Обмен между процессами, созданными с использованием модуля многопроцессорности

ответ

2

Вот пример:

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, 0 Сумма
ID 1, сумма 1
ID 2, сумма 3
...
ID 31, сумма 496
идентификатор 32, сумма 528
результат: 528

Другой вариант (никогда не использовать его в реальном проект):

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 
+1

если я ставлю четкости __init __ метод (само) и положить self.stored_value = 0 в нем и пытается получить доступ к этой переменной как proxy_object.stored_value + = 1. Почему это дает ошибку: AttributeError: Объект AutoProxy [MySharedClass] не имеет атрибута 'stored_value'. Моя точка зрения заключается в том, что я создаю одну и ту же переменную, используя класс multiprocessing Value() или Manager() и делясь ею; то мы можем получить доступ, используя оператор ссылки на объект (.). Я хочу получить доступ к объектным переменным MySharedClass() в рабочем процессе с помощью оператора ссылки на объект –

+0

Было бы неплохо использовать @property и <>. Setter decorators. Но я нашел только один способ и никогда не использовал его раньше. Это NamespaceProxy. Не знаю, какие проблемы могут возникнуть. Посмотрите на обновленный ответ. – minskster

+0

В приведенном выше решении, если я импортирую 'import eventlet' и вызывая 'eventlet.monkey_patch()' Он дает ошибку как: IOError: [Errno 11] Ресурс временно недоступен –