我有两个进程想要相互通信:
文件 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__()
方法完成分叉后才能调用 - 可能有另一种方法可以完成这部分, 当然,但我还没有找到它...
在制品代码:
我已经删除了对日志记录模块的引用 - 属性是什么并不重要。
如果您注释掉print houdiniAttribute
行,则一切按预期
工作需要明确的是,传递返回 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()
尝试澄清:
- 在流程 1
- 中创建流程对象 1
- 流程对象生成一个新进程(进程 2)
- 在进程 2 中,在同一类的另一个对象(对象 2)上调用
run()
。 -
run()
将属性分配给对象 2。 - 进程 2 完成并删除对象 2。 进程 1
- 现在知道进程 2 已完成。对象 1 仍具有旧属性。
如果你想同步东西,看看经理。多进程在进程之间共享不可序列化的对象
这回答了你的问题吗?