如何更新进程中的类成员? [英] How can I update class members in processes?

查看:54
本文介绍了如何更新进程中的类成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经寻找了其他问题,并且这个未被接受的问题是我能找到的唯一一个以某种方式涵盖了这个问题并且并没有真正帮助的.另外,我需要它来处理进程,而不是线程.

I have looked for other questions, and this un-accepted-answered question is the only one I could find that somehow covers this issue and is not really helpful. Also, I need this to work with processes, and not threads.

因此,我从头开始编写了一个示例程序来展示我的问题,您应该能够粘贴它并且它会运行:

So from the ground up I wrote a sample program to show my issue, you should be able to paste it and it will run:

import multiprocessing
import time 

class Apple:
   def __init__(self, color):
      self.color = color

def thinkAboutApple(apple):
   while True:
      print(apple.color)
      time.sleep(2)

my_apple = Apple("red")
new_process = multiprocessing.Process(target=thinkAboutApple, args=(my_apple,))
new_process.start()
time.sleep(4)
print("new: brown")
my_apple.color = "brown"

#so that the program doesn't exit after time.sleep(4)
while True:
    pass

# actual output | # wanted output
red             | red
red             | red
new: brown      | new: brown
red             | brown
red             | brown

这告诉我,要么苹果处于一个奇怪的假设,它同时是两种颜色,要么 new_process 的苹果在 ram 中处于另一个位置,并与主进程中的苹果分开.

This tells me that either the apple is in a weird supposition where it is two colours at the same time, OR that the new_process' apple is in another position in ram and separated from the apple in the main process.

所以问题是:有没有办法让进程中苹果的指针指向同一个苹果,或者pythonic的方式是什么让所有进程中苹果的所有实例都相同?如果我在许多进程中都有同一个苹果,甚至更多进程没有苹果,我如何确保它们的面积始终相同?

So the question is: Is there a way to have the pointer of the apple in the process point to the same apple, or what is the pythonic way to keep all instances of the apple in all processes the same? What if I have the same apple in many processes and even more processes without the apple, how do I make sure they area always the same?

推荐答案

您可以从(未记录的)派生 multiprocessing.BaseManager 使用的 Proxy 类的专用版本) multiprocessing.managers.NamespaceProxy 与基类不同,它公开了它的所有方法和属性.这类似于@shtse8's answer对链接的重复问题,但我在这里发布了一个可运行的答案清楚如何做到这一点.

You can derive a specialized version of a Proxy class used by multiprocessing.BaseManager from a (undocumented) multiprocessing.managers.NamespaceProxy that, unlike the base class, exposes all of its methods and attributes. This is similar to @shtse8's answer to the linked duplicate question, but I'm posting a runnable answer to it here to make clear how it can be done.

from multiprocessing import Process
from multiprocessing.managers import BaseManager, NamespaceProxy
import time
import types

class MyManager(BaseManager): pass  # Avoid namespace pollution.

class Apple:
    def __init__(self, color):
        self.color = color


def Proxy(target):
    """ Create a derived NamespaceProxy class for `target`. """
    def __getattr__(self, key):
        result = self._callmethod('__getattribute__', (key,))
        if isinstance(result, types.MethodType):
            def wrapper(*args, **kwargs):
                self._callmethod(key, args)
            return wrapper
        return result

    dic = {'types': types, '__getattr__': __getattr__}
    proxy_name = target.__name__ + "Proxy"
    ProxyType = type(proxy_name, (NamespaceProxy,), dic)  # Create subclass.
    ProxyType._exposed_ = tuple(dir(target))

    return ProxyType


AppleProxy = Proxy(Apple)


def thinkAboutApple(apple):
    while True:
        print(f"apple.color: {apple.color}")
        time.sleep(1)


if __name__ == '__main__':

    MyManager.register('Apple', Apple, AppleProxy)

    manager = MyManager()
    manager.start()

    my_apple = manager.Apple("red")
    new_process = Process(target=thinkAboutApple, args=(my_apple,))
    new_process.start()

    time.sleep(2)  # Allow other process to run a short while.
    my_apple.color = "brown"  # Change shared class instance.

    time.sleep(2)  # Allow other process to run at little while longer.
    new_process.terminate()

这篇关于如何更新进程中的类成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆