简体   繁体   English

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

[英]python sharing singleton object between child processes

I know that processes do not share same context in python. 我知道进程在python中不会共享相同的上下文。 But what about singleton objects? 但是单例对象呢? I was able to get the child process share same internal object as parent process, but am unable to understand how. 我能够使子进程与父进程共享相同的内部对象,但无法理解如何。 Is there something wrong with the code below? 下面的代码有什么问题吗?

This could be a follow up to this stackoverflow question . 这可能是此stackoverflow问题的后续措施。

This is the code I have: 这是我的代码:

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()

On forking systems, child processes have a copy on write view of the parent memory space. 在分叉系统上,子进程在父存储空间的写入视图中具有一个副本。 Processes use virtual memory and right after the fork both process virtual spaces point to the same physical RAM. 进程使用虚拟内存,并且在派生之后,两个进程虚拟空间都指向同一物理RAM。 On write, the physical page is copied and virtual memory is remapped so that bit of the the memory is no longer shared. 在写入时,将复制物理页面,并重新映射虚拟内存,以便不再共享内存的位。 This deferred copy is usually faster than cloning the memory space at the fork. 通常,此延迟的副本比在fork处克隆内存空间要快。

The result is that neither parent or child sees the other sides changes. 结果是父母或孩子都看不到对方的变化。 Since you setup the singleton before the fork, both parent and child see the same value. 由于您在派生之前设置了单例,因此父级和子级都将看到相同的值。

Here is a quick example where I use time.sleep to control when parent and child make their private changes: 这是一个简单的示例,其中我使用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)

When run: 运行时:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM