Подтвердить что ты не робот

Почему экземпляр необходимо воссоздавать при перезапуске потока?

Представьте себе следующие классы:

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 это не очень практично. Я должен прочитать текущие значения старого Object, создать новый и установить параметры в новом объекте со старыми значениями. Второй вопрос: можно ли это сделать более умным, более простым способом?

4b9b3361

Ответ 1

Причина, по которой threading.Thread реализован таким образом, заключается в поддержании соответствия между потоковым объектом и потоком операционной системы. В основных ОС потоки не могут быть перезапущены, но вы можете создать еще один поток с другим идентификатором потока.

Если рекреация является проблемой, нет необходимости наследовать ваш класс из threading.Thread, просто передайте целевой параметр конструктору Thread следующим образом:

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

Затем вы можете обратиться к члену потока, чтобы контролировать выполнение потока, и воссоздать его по мере необходимости. No MyObj не требуется.

Ответ 2

Смотрите здесь: http://docs.python.org/2/library/threading.html#threading.Thread.start

Он должен вызываться не более одного раза за объект потока. Он организует object run(), который должен быть вызван в отдельном потоке управления.

Этот метод вызывает RuntimeError, если он вызван более одного раза на тот же объект потока.

Нить не предназначена для запуска более одного раза. Возможно, вы захотите использовать пул потоков

Ответ 3

Я полагаю, что это связано с тем, как реализуется класс 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