【问题标题】:Attributes on Python multiprocessing.Process subclassesPython multiprocessing.Process 子类的属性
【发布时间】:2023-03-20 14:51:01
【问题描述】:

我有两个要相互通信的进程:

文件 hwmgr.py:

import multiprocessing as mp
from setproctitle import setproctitle
import smbus
import myLoggingModule as log

class HWManager(mp.Process):
    def __init__(self):
        mp.Process.__init__(self)
        self.i2c_lock = mp.Lock()
    def run(self):
        setproctitle('hwmgr')
        # self.logger = log.config_logger(**kwargs)
    def get_voltage(self):
        with self.i2c_lock:
            # ...do i2c stuff to get a voltage with smbus module
        # self.logger.debug('Got a voltage: %s', voltage)
        return voltage

文件 main.py:

import hwmgr

hwm = hwmgr.HWManager()
hwm.start()

battery = hwm.get_voltage()

print battery  # Works!

因此,有趣的是,按预期工作 - 电压由方法调用返回,无需任何特殊的多处理魔法。 但是,如果我启用涉及记录器的两行,当遇到 logger.debug() 调用时,我会得到:

AttributeError: 'HWManager' object has no attribute 'logger'

而且,事实上,如果我在那里打印一个dir(self),它就没有logger
我不明白吗?我的记录器去哪儿了?

记录器在run()方法中定义的原因,而不是__init__()是因为我在新进程的根记录器之后,因为记录器的文件名取自新进程标题 (getproctitle()) 直到进程在完成__init__() 方法后才能调用——当然,这部分可能有另一种方法,但我还没有找到它。 ..

WIP 代码:
我已删除对日志记录模块的引用 - 属性是什么并不重要。
如果您注释掉 print houdiniAttribute 行,一切都会按预期工作

需要明确的是,传递一个 return int 是有效的 - 消失的属性是问题

文件 hwmgr.py:

import multiprocessing as mp
from setproctitle import setproctitle
import smbus

class HWManager(mp.Process):
    def __init__(self):
        mp.Process.__init__(self)
        self.i2c_lock = mp.Lock()

    def run(self):
        setproctitle('hwmgr')
        self.houdiniAttribute = 'ASDFGHJKL'
        with self.i2c_lock:
            pass  # Set up I2C bus to take ADC readings

        while True:  # Doesn't matter if this is here...
           pass

    def get_voltage(self):
        with self.i2c_lock:
            voltage = 12.0  # Actually, do i2c stuff to get a voltage with smbus module
        print self.houdiniAttribute
        return voltage

文件client.py:

import multiprocessing as mp
from setproctitle import setproctitle
from time import sleep

class HWClient(mp.Process):
    def __init__(self, hwm):
        mp.Process.__init__(self)
        self.hwm = hwm

    def run(self):
        setproctitle('client')
        while True:
            battery = self.hwm.get_voltage()
            print battery
            sleep(5)

文件 main.py:

import hwmgr
import client

hwm = hwmgr.HWManager()
hwm.start()
cl = client.HWClient(hwm)
cl.start()

【问题讨论】:

  • 要为您的问题添加信息,请单击问题下方的“编辑”链接,而不是发布新问题并链接到原始问题。实际上,您所拥有的原始问题可能会因为“过于宽泛”而被关闭,但是如果您将它与这个尝试的解决方案结合起来(为了简洁起见,我建议进行一些编辑),那么我认为它值得点赞。
  • 此外,似乎在 run 方法中添加的任何属性都消失了,并且不再可以在其他方法中访问。这是变量范围的问题吗?
  • mod 注意:最初这个问题是对离题设计/讨论问题的引用。没有办法撤回标志,但我不再认为应该删除这个标志并将其合并到另一个问题中,因为 OP 删除了另一个问题并编辑了这个问题以使其成为一个独立的问题。

标签: python logging multiprocessing


【解决方案1】:

尝试澄清:

  1. 您在进程 1 中创建进程对象 1
  2. 进程对象产生一个新进程(进程 2)
  3. 在进程 2 中,run() 在同一类的另一个对象(对象 2)上被调用。
  4. run() 将属性分配给对象 2。
  5. 进程 2 完成并移除对象 2。
  6. 进程 1 现在知道进程 2 已完成。对象 1 仍然具有旧属性。

如果您想同步内容,请查看管理器。 Multiprocessing Share Unserializable Objects Between Processes

这能回答你的问题吗?

【讨论】:

  • 即使我在self.logger = log... 行之后添加while True: pass 之类的内容(即,因此HWManager 永远不会“完成”),对记录器的引用仍然不起作用 - 但对其的引用方法工作得很好。我可以从main.py 给他们打电话,没有任何戏剧性。这实际上不是关于序列化或同步的问题——HWManager 是一个类/进程,是众多进程之一,它们都是从原始脚本文件中产生的。我正在寻找其他衍生进程调用硬件管理器上的方法并获取返回值的某种方式。
  • 你读过链接的问题和提到的问题吗?它可能会有所帮助。到目前为止,我确实看到您的问题等于stackoverflow.com/questions/19468885/…
  • 如果我理解正确,链接的问题会讨论进程之间的对象同步。我在进程之间移动数据没有任何问题 - 尝试运行上面的 WIP 代码,并注释掉 print houdiniAttribute 行 - 工作正常。我不明白的是,当线路启用时,该属性在哪里。
  • 我也应该指出 - HWManager 的重点是继续运行 - 这不是要完成然后退出的“工作”。这是嵌入式系统的硬件管理器,因此 HWManager 进程将继续运行,其他进程会向它请求服务——比如“给我电池电压,以便我记录它”,或“关闭继电器输出,然后告诉我”如果成功”。其他 proc 在创建时都引用了硬件管理器(就像在 WIP 代码中一样),所以这似乎可行——除了我希望 HWManager 记录其活动。
  • 那么,我的新 mp.Process 对象的原始副本是接收 main 发送的消息的那个,而不是分叉后产生的副本?
猜你喜欢
  • 2012-01-19
  • 1970-01-01
  • 2017-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多