python在子进程之间共享单例对象

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python在子进程之间共享单例对象相关的知识,希望对你有一定的参考价值。

我知道进程在python中不共享相同的上下文。但单身对象怎么样?我能够让子进程共享相同的内部对象作为父进程,但我无法理解如何。下面的代码有什么问题吗?

这可能是this stackoverflow question的后续行动。

这是我的代码:

Singleton.py:


import os

class MetaSingleton(type):
     _instances = {}

def __call__(cls, *args, **kwargs):
    if cls not in cls._instances:
        cls._instances[cls] = super(MetaSingleton, cls).__call__(*args, **kwargs)
    return cls._instances[cls]

class Singleton:
   __metaclass__ = MetaSingleton

   def __init__(self):
       self.key="KEY TEST"
       print "inside init"

   def getKey(self):
       return self.key

  def setKey(self,key1):
       self.key = key1

  process_singleton.py:


  import os
  from Singleton import Singleton

  def callChildProc():
       singleton = Singleton()
       print ("singleton key: %s"%singleton.getKey())

  def taskRun():
       singleton = Singleton()
       singleton.setKey("TEST2")
       for i in range(1,10):
           print ("In parent process, singleton key: %s" %singleton.getKey())
        try:
           pid = os.fork()
        except OSError,e:
           print("Could not create a child process: %s"%e)

        if pid == 0:
            print("In the child process that has the PID %d"%(os.getpid()))
           callChildProc()
           exit()

       print("Back to the parent process")

 taskRun()
答案

在分叉系统上,子进程在父内存空间的写视图上有一个副本。进程使用虚拟内存,在fork之后,两个进程虚拟空间都指向相同的物理RAM。在写入时,将复制物理页面并重新映射虚拟内存,以便不再共享内存位。这个延迟副本通常比克隆fork的内存空间更快。

结果是父母或孩子都看不到其他方面的变化。由于您在fork之前设置了单例,因此父级和子级都会看到相同的值。

这是一个快速示例,我使用time.sleep来控制父母和孩子何时进行私人更改:

import multiprocessing as mp
import time

def proc():
    global foo
    time.sleep(1)
    print('child foo should be 1, the value before the fork:', foo)
    foo = 3 # child private copy


foo = 1 # the value both see at fork
p = mp.Process(target=proc)
p.start()
foo = 2 # parent private copy
time.sleep(2)
print('parent foo should be 2, not the 3 set by child:', foo)

运行时:

child foo should be 1, the value before the fork: 1
parent foo should be 2, not the 3 set by child: 2

以上是关于python在子进程之间共享单例对象的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 多处理进程中运行较慢的 OpenCV 代码片段

Python进程与线程

Python 在进程之间共享锁

python多线程

Python在进程之间共享锁定

python中的多处理-在多个进程之间共享大对象(例如pandas数据框)