如何检测Python线程是否被杀死?

时间:2019-06-26 13:30:13

标签: python multithreading python-multithreading

我有一个名为Thread的{​​{1}}。我想在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") 在其他线程超时之前5秒钟释放主线程。因此,我收到的前2封电子邮件带有“ DEBUG_0”和“ DEBUG_1”,但没有收到最后一封“ DEBUG_2”,因为主进程在超时完成之前就退出了。

我想链接类time.sleep(5)和函数TimeBasedLogThread,该函数将在退出前刷新(发送电子邮件)。我怎样才能做到这一点?我看着my_function的{​​{3}},但不知道可以使用哪种方法。

2 个答案:

答案 0 :(得分:0)

也将您的函数构建为线程。 (例如:AfterDeadThread)

您在这里有两种策略:

  • TimeBasedLogThread在死之前调用AfterDeadThread
  • AfterDeadThread检查TimeBasedLogThread是否处于活动状态,否则将运行某些方法

答案 1 :(得分:0)

扩展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