如何从另一个multiprocessing.Process实例中的方法返回值?
我有两个文件:
文件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, cmd_q, res_q)
self.i2c_lock = mp.Lock()
self.commandQueue = cmd_q
self.responseQueue = res_q
def run(self):
setproctitle('hwmgr')
while True:
cmd, args = self.commandQueue.get()
if cmd is None: self.terminate()
method = self.__getattribute__(cmd)
result = method(**args)
if result is not None:
self.responseQueue.put(result)
def get_voltage(self):
with self.i2c_lock:
# ...do i2c stuff to get a voltage with smbus module
return voltage
文件main.py:
import multiprocessing as mp
import hwmgr
cmd_q = mp.Queue()
res_q = mp.Queue()
hwm = hwmgr.HWManager(cmd_q, res_q)
hwm.start()
cmd_q.put(('get_voltage', {}))
battery = res_q.get()
print battery
虽然这个解决方案有效,但HWManager过程的复杂性很可能会在未来增长,而其他过程则会产生main.py(代码简化),它们使用相同的机制。很明显,错误的进程可能会从res_q.get()
命令中获取错误的返回数据。
这样做会更有效吗?
(我试图避免为每个其他进程返回一个mp.Queue
- 因为这需要每次重新处理HWManager类以容纳其他队列)
确定 - WIP代码如下:
hwmgr.py:
import multiprocessing as mp
from multiprocessing.connection import Listener
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.listener = Listener('/tmp/hw_sock', 'AF_UNIX')
with self.i2c_lock:
pass # Set up I2C bus to take ADC readings
while True:
conn = self.listener.accept()
cmd, args = conn.recv()
if cmd is None: self.terminate()
method = self.__getattribute__(cmd)
result = method(**args)
conn.send(result)
def get_voltage(self):
with self.i2c_lock:
voltage = 12.0 # Actually, do i2c stuff to get a voltage with smbus module
return voltage
file client.py
import multiprocessing as mp
from multiprocessing.connection import Client
from setproctitle import setproctitle
from time import sleep
class HWClient(mp.Process):
def __init__(self):
mp.Process.__init__(self)
self.client = Client('/tmp/hw_sock', 'AF_UNIX')
def run(self):
setproctitle('client')
while True:
self.client.send(('get_voltage', {}))
battery = self.client.recv()
print battery
sleep(5)
main.py:
import hwmgr
import client
cl = client.HWClient() # Put these lines here = one error (conn refused)
cl.start()
hwm = hwmgr.HWManager()
hwm.start()
# cl = client.HWClient() # ...Or here, gives the other (in use)
# cl.start()
答案 0 :(得分:1)
这听起来像是需要标准的客户端 - 服务器架构。您可以使用UNIX域套接字(或Windows上的命名管道)。多处理模块使得在进程之间传递python对象变得非常容易。服务器代码的示例结构:
from multiprocessing.connection import Listener
listener = Listener('somefile', 'AF_UNIX')
queue = Queue()
def worker():
while True:
conn, cmd = queue.get()
result = execute_cmd(cmd)
conn.send(result)
queue.task_done()
for i in range(num_worker_threads):
t = Thread(target=worker)
t.daemon = True
t.start()
while True:
conn = listener.accept()
cmd = conn.recv()
queue.put((conn, cmd)) # Do processing of the queue in another thread/process and write result to conn
客户端看起来像:
from multiprocessing.connection import Client
client = Client('somefile', 'AF_UNIX')
client.send(cmd)
result = client.recv()
上面的代码使用了工作线程,但您可以轻松地为使用多处理模块的工作人员创建流程。有关详细信息,请参阅docs。