如何在 Python 中同时运行多个循环?

91 阅读2分钟

有这样一个 Python 项目,需要发送硬件(Phidgets)命令。由于需要与多个硬件组件进行交互,所以需要同时运行多个循环。

huake_00210_.jpg 已经研究了 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 模块。其文档也是一篇很好的读物,可以探索它的全部潜力。