【问题标题】:python Class Object Sharing between Processes created using multiprocessing module使用多处理模块创建的进程之间的python类对象共享
【发布时间】:2016-06-13 12:41:04
【问题描述】:

如何创建可以由工作进程修改的我的类的 python 共享对象。我使用 multiprocessing.Process 模块创建了工作进程。我对 multiprocessing.Manager 模块有一些了解。任何人都可以举例说明如何将我的类注册到管理器,启动管理器并创建我的类的共享对象。

【问题讨论】:

    标签: python python-2.7 operating-system


    【解决方案1】:

    这是一个例子:

    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
    id 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
    

    【讨论】:

    • 如果我放入 def __init__(self) 方法并将 self.stored_value = 0 放入其中并尝试访问此变量,如 proxy_object.stored_value += 1。为什么它给出错误:AttributeError:' AutoProxy[MySharedClass]' 对象没有属性 'stored_value'。我的观点是,如果我使用多处理 Value() 或 Manager() 类创建相同的变量并共享它;然后我们可以使用对象引用运算符 (.) 进行访问。我想使用对象引用运算符访问工作进程中 MySharedClass() 的对象变量
    • 使用 @property 和 .setter 装饰器会很好。但是我只找到了一种方法,以前从未使用过。它是命名空间代理。不知道会出现什么样的问题。查看更新后的答案。
    • 在上述解决方案中,如果我正在导入“import eventlet”并调用“eventlet.monkey_patch()”,则会出现错误:IOError: [Errno 11] Resource暂时不可用
    • 我从未使用过 eventlet,将尝试获得时间,但我有一个具有多处理、gevent(另一个并发网络库)、flask 和 websocket 的应用程序。让所有这些都可以一起工作是一个问题。我花了很多时间寻找所有包 gevent、gevent-socketio、greenlet ... 的兼容版本。
    猜你喜欢
    • 2020-06-25
    • 1970-01-01
    • 2017-02-02
    • 2012-07-22
    • 2023-03-24
    • 2010-10-14
    • 2017-04-01
    • 2014-04-24
    • 2020-11-13
    相关资源
    最近更新 更多