如何进行线程化。线程的 start() 调用 run() 以外的方法



我有一个类,它有两个方法run()run_forever(),后者反复调用前者。我想在不同的线程上运行run_forever()类的不同实例,但到目前为止,我还不能偏离threading.Thread调用run()的默认行为。

这是我想要实现的一个简化版本:

import time
import threading
class Controller(object):
    def run(self):
        print("Running once...")
    def run_forever(self):
        while True:
            self.run()
            time.sleep(1)
class ThreadController(Controller, threading.Thread):
    def __init__(self, *args, **kwargs):
        Controller.__init__(self, *args, **kwargs)
        threading.Thread.__init__(self, target=self.run_forever)
if __name__ == "__main__":
    thread_controller = ThreadController()
    thread_controller.start()
    thread_controller.join()

如果我运行这个脚本,它只打印一次Running once...,而不是像我在threading.Thread的初始化中设置target=self.run_forever时那样每秒打印一次。如何修改此代码以实现所需的行为?

停止继承Controller:

controller = Controller()
thread = threading.Thread(target=controller.run_forever)

您实际上覆盖了线程的run方法:您的ThreadController继承自ControllerThread,并且Controller类实现了自己的run

From the docs:

标准的run()方法调用作为目标参数传递给对象构造函数的可调用对象

但是你的run没有调用任何东西(不做任何与目标)。它只打印一次Running…您看到的单个print是试图执行其run()方法的Thread。嗯…尝试并实际上成功了。; -)

要解决这个问题(尽管我个人认为可能会更改代码并尽量避免双重继承),将Controller.run的名称更改为.do:
class Controller(object):
    def do(self):
        print("Running once...")
    def run_forever(self):
        while True:
            self.do()
            time.sleep(1)

正如前面提到的,我也不喜欢多重继承,而是让带有run方法的类成为线程本身。这使得ThreadController名副其实。我可以建议以下的重复代码:

class MyThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self, target=self.run_forever)
    def do(self):
        print("Running once...")
    def run_forever(self):
        while True:
            self.do()
            time.sleep(1)
class ThreadController(object):
    def __init__(self, *args, **kwargs):
        c = MyThread()
        c.start()
        c.join()
if __name__ == "__main__":
    thread_controller = ThreadController()

当然,除了可以将run_forever重命名为run并省略构造函数的target参数之外,但我尊重这篇文章的标题:-)。

我认为你想要控制器从线程继承,然后不要覆盖run;

from threading import Thread
class Controller(Thread):
    def __init__(self, *args, **kwargs):
        super(Controller, self).__init__(*args, **kwargs)
    def run_once(*args, **kwargs):
        print("Running once...")
    def run_forever(*args, **kwargs):
        print("Running forever...")

运行一次;

Controller(target=Controller.run_once).start()

永远运行;

Controller(target=Controller.run_forever).start()

最新更新