[英]Pass method return values between multiprocessing.Process instances
如何從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類以容納其他隊列)
OK-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
文件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()
聽起來這需要標准的客戶端-服務器體系結構。 您可以使用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()
上面的代碼為工作人員使用線程,但是您可以使用多處理模塊輕松地為工作人員提供進程。 有關詳細信息,請參閱文檔 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.