Python 为什么重启线程时需要重新创建实例?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14293368/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 10:59:36  来源:igfitidea点击:

Why does the instance need to be recreated when restarting a thread?

pythonmultithreading

提问by OrangeTux

Imagine the following classes:

想象一下以下类:

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()

I want to restart the thread in case it is dead. This doens't work. Because the threads can only be started once. First question. Why is this?

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

For as far as I know I have to recreate each instance of Objectand call start()to start the thread again. In case of complex Objects this is not very practical. I've to read the current values of the old Object, create a new one and set the parameters in the new object with the old values. Second question: Can this be done in a smarter, easier way?

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

采纳答案by Ellioh

The reason why threading.Thread is implemented that way is to keep correspondence between a thread object and operating system's thread. In major OSs threads can not be restarted, but you may create another thread with another thread id.

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

If recreation is a problem, there is no need to inherit your class from threading.Thread, just pass a target parameter to Thread's constructor like this:

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

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

Then you may access thread member to control your thread execution, and recreate it as needed. No MyObj recreation is required.

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

回答by Simbi

See here: http://docs.python.org/2/library/threading.html#threading.Thread.start

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

It must be called at most once per thread object. It arranges for the object's run() method to be invoked in a separate thread of control.

This method will raise a RuntimeError if called more than once on the same thread object.

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

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

A thread isn't intended to run more than once. You might want to use a Thread Pool

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

回答by bereal

I believe, that has to do with how Threadclass is implemented. It wraps a real OS thread, so that restarting the thread would actually change its identity, which might be confusing.

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

A better way to deal with threads is actually through target functions/callables:

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

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