zoukankan      html  css  js  c++  java
  • Python通过Manager方式实现多个无关联进程共享数据

    Python实现多进程间通信的方式有很多种,例如队列,管道等。
    但是这些方式只适用于多个进程都是源于同一个父进程的情况。
    如果多个进程不是源于同一个父进程,只能用共享内存,信号量等方式,但是这些方式对于复杂的数据结构,例如Queue,dict,list等,使用起来比较麻烦,不够灵活。
    Manager是一种较为高级的多进程通信方式,它能支持Python支持的的任何数据结构。
    它的原理是:先启动一个ManagerServer进程,这个进程是阻塞的,它监听一个socket,然后其他进程(ManagerClient)通过socket来连接到ManagerServer,实现通信。

    manager.py代码,实现server和client两个类

    # encoding=utf-8
    __author__ = 'kevinlu1010@qq.com'
    '''
    进程间通信
    '''
    from multiprocessing.managers import BaseManager
    from multiprocessing import RLock
    
    MANAGER_PORT = 6000
    MANAGER_DOMAIN = '0.0.0.0'
    MANAGER_AUTH_KEY = 'aaaaaaaaaaaaaaa'
    
    #定义一个Manager类
    class InfoManager(BaseManager): pass
    
    
    class DictItem():
        def __init__(self, ):
            self.items = dict()
    
        def set(self, key, value):
            self.items[key] = value
    
        def get(self, key):
            return self.items.get(key)
    
        def __setitem__(self, key, value):
            self.set(key, value)
    
    #为这个manager类注册存储容器,也就是通过这个manager类实现的共享的变量,
    #这个变量最好是一个类实例,自己定义的或者python自动的类的实例都可以
    #这里不能把d改成dict(),因为Client那边执行d['keyi']='value'的时候会报错:d这个变量不能修改
    d = DictItem()
    lock = RLock()
    InfoManager.register('dict', callable=lambda: d)
    InfoManager.register('open_qq_login_lock', callable=lambda: lock)
    
    
    class ManagerServer():
        '''
        multiprocess Manager服务类
        '''
    
        def __init__(self, domain, port, auth_key):
            self.domain = domain
            self.port = port
            self.auth_key = auth_key
    
        def start_manager_server(self):
            self.queue_manager = InfoManager(address=('', self.port), authkey=self.auth_key)
            # self.dict = self.queue_manager.dict()
            self.server = self.queue_manager.get_server()
    
        def run(self):
            self.start_manager_server()
            self.server.serve_forever()
    
        def stop(self):
            self.server.shutdown()
            self.is_stop = 1
    
    
    class ManagerClient():
        '''
        访问mutiprocess Manager的类
        '''
    
        def __init__(self, domain, port, auth_key):
            self.domain = domain
            self.port = port
            self.auth_key = auth_key
            # self.get_share_dict()
            self.info_manager = InfoManager(address=(self.domain, self.port), authkey=self.auth_key)
            self.info_manager.connect()
    
        def get_dict(self):
            # self.dict = m.dict()
            self.dict = self.info_manager.dict()
            return self.dict
    
        def get_open_qq_login_lock(self):
            self.open_qq_login_lock = self.info_manager.open_qq_login_lock()
            return self.open_qq_login_lock
    
    
    if __name__ == '__main__':
        pass

    用法
    1.启动一个ManagerServer,这个进程是阻塞的

    import manager
    
    def run():
        manager_server = manager.ManagerServer(manager.MANAGER_DOMAIN, manager.MANAGER_PORT, manager.MANAGER_AUTH_KEY)
        manager_server.run()
    if __name__ == '__main__':
        run()

    2.实例化一个client,获取共享的变量

    # 进程间共享变量
    manager_client = manager.ManagerClient(manager.MANAGER_DOMAIN, manager.MANAGER_PORT, manager.MANAGER_AUTH_KEY)
    share_dict = manager_client.get_dict()
    open_qq_login_lock = manager_client.get_open_qq_login_lock()

    注意:
    1.对client获取的变量修改,不会影响server那边的变量,例如server中,client1获取变量params1,把它修改为params2,server那边的数据不会修改。如果要修改server的数据,需要调用server的方法,把server那边的数据刷新。

  • 相关阅读:
    Best Time to Buy and Sell Stock
    Remove Nth Node From End of List
    Unique Paths
    Swap Nodes in Pairs
    Convert Sorted Array to Binary Search Tree
    Populating Next Right Pointers in Each Node
    Maximum Subarray
    Climbing Stairs
    Unique Binary Search Trees
    Remove Duplicates from Sorted Array
  • 原文地址:https://www.cnblogs.com/ExMan/p/10187577.html
Copyright © 2011-2022 走看看