13

想象以下类:

Class Object(threading.Thread):
    # some initialisation blabla
    def run(self):
        while True:
            # do something
            sleep(1)

class Checker():
    def check_if_thread_is_alive(self):
        o = Object()
        o.start()

        while True:
            if not o.is_alive():
                o.start()

我想重新启动线程以防它死了。这行不通。因为线程只能启动一次。第一个问题。为什么是这样?

据我所知,我必须重新创建每个实例Object并调用start()以再次启动线程。在复杂Object的情况下,这不是很实用。我必须读取 old 的当前值Object,创建一个新值并使用旧值设置新对象中的参数。第二个问题:这可以以更智能、更简单的方式完成吗?

4

3 回答 3

17

以这种方式实现 threading.Thread 的原因是为了保持线程对象和操作系统线程之间的对应关系。在主要操作系统中,线程无法重新启动,但您可以使用另一个线程 id创建另一个线程。

如果娱乐是一个问题,则无需从 threading.Thread 继承您的类,只需将目标参数传递给 Thread 的构造函数,如下所示:

class MyObj(object):
    def __init__(self):
        self.thread = threading.Thread(target=self.run)
    def run(self):
        ...

然后你可以访问线程成员来控制你的线程执行,并根据需要重新创建它。不需要 MyObj 娱乐。

于 2013-01-12T12:43:57.320 回答
1

见这里: http ://docs.python.org/2/library/threading.html#threading.Thread.start

每个线程对象最多只能调用一次。它安排在单独的控制线程中调用对象的 run() 方法。

如果在同一个线程对象上多次调用此方法,则会引发 RuntimeError。

一个线程不打算多次运行。您可能想使用线程池

于 2013-01-12T12:44:04.063 回答
0

我相信,这与Thread类的实现方式有关。它包装了一个真正的操作系统线程,因此重新启动线程实际上会改变它的身份,这可能会令人困惑。

处理线程的更好方法实际上是通过目标函数/可调用对象:

class Worker(object):
    """ Implements the logic to be run in separate threads """
    def __call__(self):
        #  do useful stuff and change the state

class Supervisor():
    def run(self, worker):
        thr = None
        while True:
            if not thr or not thr.is_alive():
                thr = Thread(target=worker)
                thr.daemon = True
                thr.start()
            thr.join(1)  # give it some time
于 2013-01-12T12:48:57.840 回答