有这样一个 Python 项目,需要发送硬件(Phidgets)命令。由于需要与多个硬件组件进行交互,所以需要同时运行多个循环。
已经研究了 Python 中的多进程模块 multiprocessing,但事实证明硬件一次只能由一个进程控制,因此所有循环都需要在同一个进程中运行。
目前,可以通过一个 Tk() 循环来完成任务,但并没有真正使用任何 GUI 工具。例如:
from Tk import tk
class hardwareCommand:
def __init__(self):
# Define Tk object
self.root = tk()
# open the hardware, set up self. variables, call the other functions
self.hardwareLoop()
self.UDPListenLoop()
self.eventListenLoop()
# start the Tk loop
self.root.mainloop()
def hardwareLoop(self):
# Timed processing with the hardware
setHardwareState(self.state)
self.root.after(100,self.hardwareLoop)
def UDPListenLoop(self):
# Listen for commands from UDP, call appropriate functions
self.state = updateState(self.state)
self.root.after(2000,self.UDPListenLoop)
def eventListenLoop(self,event):
if event == importantEvent:
self.state = updateState(self.event.state)
self.root.after(2000,self.eventListenLoop)
hardwareCommand()
所以,定义 Tk() 循环的唯一原因是为了能够在那些需要并发循环的函数中调用 root.after() 命令。
这种方法有效,但有没有更好的/更符合 Python 风格的方法来实现这一点?还要想知道这种方法是否会导致不必要的计算开销(我不是计算机科学专业人士)。
2、解决方案
多进程模块 multiprocessing 旨在处理多个独立的进程。虽然可以使用 Tk 的事件循环,但如果没有基于 Tk 的 GUI,就没有必要这样做。因此,如果只是想让多个任务在同一个进程中执行,可以使用 Thread 模块。通过它,可以创建封装了单独执行线程的特定类,从而可以在后台同时执行许多“循环”。可以考虑类似这样的代码:
from threading import Thread
class hardwareTasks(Thread):
def hardwareSpecificFunction(self):
"""
Example hardware specific task
"""
#do something useful
return
def run(self):
"""
Loop running hardware tasks
"""
while True:
#do something
hardwareSpecificTask()
class eventListen(Thread):
def eventHandlingSpecificFunction(self):
"""
Example event handling specific task
"""
#do something useful
return
def run(self):
"""
Loop treating events
"""
while True:
#do something
eventHandlingSpecificFunction()
if __name__ == '__main__':
# Instantiate specific classes
hw_tasks = hardwareTasks()
event_tasks = eventListen()
# This will start each specific loop in the background (the 'run' method)
hw_tasks.start()
event_tasks.start()
while True:
#do something (main loop)
可以阅读这篇文章来进一步熟悉 threading 模块。其文档也是一篇很好的读物,可以探索它的全部潜力。