代码之家  ›  专栏  ›  技术社区  ›  Kallz

在多处理中生成单例类

  •  6
  • Kallz  · 技术社区  · 9 年前

    我使用 它 在多线程中工作良好 只创建MySingleton类的一个实例,但在多处理中,它总是创建新实例

    import multiprocessing
    
    class SingletonType(type):
        # meta class for making a class singleton
        def __call__(cls, *args, **kwargs):
    
            try:
                return cls.__instance
            except AttributeError:
                cls.__instance = super(SingletonType, cls).__call__(*args, **kwargs)
                return cls.__instance
    
    class MySingleton(object):
        # singleton class
        __metaclass__ = SingletonType
    
        def __init__(*args,**kwargs):
            print "init called"
    
    
    def task():
        # create singleton class instance
        a = MySingleton()
    
    
    # create two process
    pro_1 = multiprocessing.Process(target=task)
    pro_2 = multiprocessing.Process(target=task)
    
    # start process
    pro_1.start()
    pro_2.start()
    

    init called
    init called
    

    我需要上MySingleton课 初始化

    1 回复  |  直到 9 年前
        1
  •  8
  •   Florian Brucker    9 年前

    您的每个子进程都运行自己的Python解释器实例,因此 SingletonType 在一个进程中,不会与另一个进程中的进程共享其状态。这意味着一个只存在于一个进程中的真正单例将几乎没有用处,因为你将无法在其他进程中使用它:而你可以 manually share data between processes ,这仅限于基本数据类型(例如dict和list)。

    #!/usr/bin/env python3
    
    import multiprocessing
    import os
    
    
    def log(s):
        print('{}: {}'.format(os.getpid(), s))
    
    
    class PseudoSingleton(object):
    
        def __init__(*args,**kwargs):
            if not shared_state:
                log('Initializating shared state')
                with shared_state_lock:
                    shared_state['x'] = 1
                    shared_state['y'] = 2
                log('Shared state initialized')
            else:
                log('Shared state was already initalized: {}'.format(shared_state))
    
    
    def task():
        a = PseudoSingleton()
    
    
    if __name__ == '__main__':
        # We need the __main__ guard so that this part is only executed in
        # the parent
    
        log('Communication setup')
        shared_state = multiprocessing.Manager().dict()
        shared_state_lock = multiprocessing.Lock()
    
        # create two process
        log('Start child processes')
        pro_1 = multiprocessing.Process(target=task)
        pro_2 = multiprocessing.Process(target=task)
        pro_1.start()
        pro_2.start()
    
        # Wait until processes have finished
        # See https://stackoverflow.com/a/25456494/857390
        log('Wait for children')
        pro_1.join()
        pro_2.join()
    
        log('Done')
    

    这张照片

    16194: Communication setup
    16194: Start child processes
    16194: Wait for children
    16200: Initializating shared state
    16200: Shared state initialized
    16201: Shared state was already initalized: {'x': 1, 'y': 2}
    16194: Done
    

    然而,根据您的问题设置,使用其他进程间通信机制可能会有更好的解决方案。例如 Queue class