Как определить, убит ли поток Python? - PullRequest
1 голос
/ 26 июня 2019

У меня есть свой Thread, который называется TimeBasedLogThread.Я хотел бы запустить функцию my_function, когда TimeBasedLogThread уничтожается, потому что основной процесс завершается.Я хотел бы сделать это изнутри этого объекта.Возможно ли это сделать?

Вот мой текущий подход:

class TimeBasedBufferingHandler(MemoryHandler):
    # This is a logging-based handler that buffers logs to send
    # them as emails
    # the target of this handler is a SMTPHandler

    def __init__(self, capacity=10, flushLevel=logging.ERROR, target=None,
                 flushOnClose=True, timeout=60):
        MemoryHandler.__init__(self, capacity=capacity, flushLevel=flushLevel, 
                                     target=target, flushOnClose=flushOnClose)
        self.timeout = timeout  # in seconds (as time.time())

    def flush(self):
         # Send the emails that are younger than timeout, all together
         # in the same email

class TimeBasedLogThread(Thread):
    def __init__(self, handler, timeout=60):
        Thread.__init__(self)
        self.handler = handler
        self.timeout = timeout

    def run(self):
        while True:
            self.handler.flush()
            time.sleep(self.timeout)

    def my_function(self):
        print("my_function is being called")
        self.handler.flush()


def setup_thread():
    smtp_handler = SMTPHandler()
    new_thread = TimeBasedLogThread(smtp_handler, timeout=10)
    new_thread.start()

В моей основной теме у меня есть:

setup_thread()

logging.error("DEBUG_0")
time.sleep(5)
logging.error("DEBUG_1")
time.sleep(5)
logging.error("DEBUG_2")

Выпуски time.sleep(5)основной поток за 5 секунд до истечения времени ожидания моего другого потока.Итак, я получаю первые 2 электронных письма с «DEBUG_0» и «DEBUG_1», но не с последним «DEBUG_2», потому что основной процесс завершается до истечения времени ожидания.

Я хотел бы связать класс TimeBasedLogThread и функция my_function, которая будет сбрасывать (отправлять электронные письма) перед выходом.Как я могу это сделать?Я посмотрел на исходный код из threading, но я не понимал, какой метод я мог бы использовать.

Ответы [ 2 ]

0 голосов
/ 26 июня 2019

Расширьте метод run() (представляющий активность потока) для запуска обработчика on_terminate, переданного конструктору пользовательского потока в качестве аргумента ключевого слова.

Для слегка измененного пользовательского класса потока (для демонстрации):

from threading import Thread
import time, random

class TimeBasedLogThread(Thread):
    def __init__(self, handler, timeout=2, on_terminate=None):
        Thread.__init__(self)
        self.handler = handler
        self.timeout = timeout
        self.terminate_handler = on_terminate

    def run(self):
        while True:
            num = self.handler()
            if num > 5:
                break
            time.sleep(self.timeout)
            print(num)

        if self.terminate_handler:
            self.terminate_handler()


def my_term_function():
    print("my_function is being called")


f = lambda: random.randint(3, 10)

tlog_thread = TimeBasedLogThread(f, on_terminate=my_term_function)
tlog_thread.start()
tlog_thread.join()

Пример вывода:

3
4
5
4
5
my_function is being called
0 голосов
/ 26 июня 2019

Создайте свою функцию как поток тоже.(Например: AfterDeadThread)

У вас есть две стратегии:

  • Вызов TimeBasedLogThread AfterDeadThread перед смертью
  • AfterDeadThread проверяет, активен ли TimeBasedLogThread, если нет, будетзапустить несколько методов
...