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

    Python官方文档
    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那边的数据刷新。

  • 相关阅读:
    数据库查询服务框架
    postgresql清理工具
    postgre索引
    SAP模块一句话入门(专业术语的理解)
    SAP订单结算详解
    SAP Datasheet
    ASP.NET MVC5 网站开发实践
    VMware S/4 HANA OP 1511虚拟机下载,64G内存限制解决方案
    SAP标准教材列表
    SAP文章链接
  • 原文地址:https://www.cnblogs.com/Xjng/p/4902514.html
Copyright © 2011-2022 走看看