【问题标题】:Python: detect if the parent thread called exit()Python:检测父线程是否调用了exit()
【发布时间】:2019-01-29 01:07:09
【问题描述】:

我有这个线程在后台运行,可以从主线程更新:

import threading
from Queue import Queue
from time import sleep

class Animation(threading.Thread):

    SIGNAL_STOP = 'stop'

    def __init__(self, framerate):
        threading.Thread.__init__(self)
        self.queue = Queue()
        self.framerate = framerate

    def tell(self, data):
        self.queue.put(data)

    def stop(self):
        self.tell(Animation.SIGNAL_STOP)

    def loop(self):
        # Override this method to implement animation loop
        pass

    def update(self, data):
        # Override this method to implement the state update
        pass

    def cleanup(self):
       # Override this method to implement what's done when the animation is stopped
       pass

    def run(self):
        while True:
            if not self.queue.empty():
                data = self.queue.get()
                if data == Animation.SIGNAL_STOP:
                    break;
                self.update(data)
            self.loop()
            sleep(1. / self.framerate)

        self.cleanup()


class TestAnimation(Animation):
    def __init__(self, framerate):
        super(TestAnimation, self).__init__(framerate)
        self.num = 0

    def loop(self):
        print 'num =', self.num
        self.num = self.num + 1

    def update(self, data):
        print 'update:', data

    def cleanup(self):
        print 'graceful exit'

print 'start'
ta = TestAnimation(1)
ta.start()
sleep(3)
ta.update(123)
sleep(3)
#ta.stop() # I'd like the animation thread to feel that the parent wants to exit and carry out stopping itself
print 'end'
exit()

我想实现一些方法来检测父线程何时想要退出,然后所有正在运行的线程都会优雅地终止自己。我更喜欢这样,而不是显式调用正在运行的线程的 stop() 方法。

【问题讨论】:

    标签: python multithreading


    【解决方案1】:

    我相信您可以将其设为daemon 线程,因此当主线程退出时,所有守护线程都会随之退出。

    所以你可以在你的构造函数中默认为daemon = True,或者在start之前设置它

    ta = TestAnimation(1)
    ta.daemon = True
    ta.start()
    

    编辑。由于需要清理线程。

    您可以使用thread.Eventatexit 的组合来向守护线程发出信号以在退出前进行清理。

    这是一个简单的例子:

    import time
    import threading
    import atexit
    
    signal_to_threads = threading.Event()  # Global signal for threads to stop.
    
    registered_threads = [] # Register all threads into here. 
    
    @atexit.register
    def signal_threads():
        print('signaling threads to stop')
        signal_to_threads.set()
        for thread in registered_threads:
            thread.signal.wait()
    
    
    class TestExit(threading.Thread):
        def __init__(self, *args, **kw):
            registered_threads.append(self)
            self.signal = threading.Event()
            super(TestExit, self).__init__(*args, **kw)
            self.daemon = True  # Ensure is a daemon thread.
    
        def run(self):
            while True:
                time.sleep(3)
                print('Hi from child thread')
                if signal_to_threads.is_set():
                    print('stopping child thread and doing cleanup.')
                    # self.do_cleanup()
                    self.signal.set()
                    break
    
    
    t = TestExit()
    t.start()
    print('sleeping for 10 secs.')
    time.sleep(10)
    print('exiting main thread')
    

    演示:

    python test_thread.py
    sleeping for 10 secs.
    Hi from child thread
    Hi from child thread
    Hi from child thread
    exiting main thread
    signaling threads to stop
    Hi from child thread
    stopping child thread and doing clean up.
    

    由于atexit 应该在退出时运行已注册的函数,因此无需跟上每个退出点来清理线程。

    【讨论】:

    • 好的,但是后台线程如何检测到主线程正在退出,以便清理东西?
    • @Passiday 不确定还有什么比您已经在做的更简单的事情。你的方法有什么问题? (或许可以根据答案改进)
    • @Passiday:您可以使用全局变量(可能与Lock 结合使用以防止并发访问)并让线程定期检查它。另一种选择是使用Queue 发送“退出”消息。
    • 当我看到主线程 exit() 没有杀死后台线程时,我希望它可以在线程中以某种方式被检测到。我只是不想在主线程可以退出的每个点显式调用线程停止。我希望线程可以优雅地停止自己。
    • @Passiday 使用 threading.Eventatexit 更新答案以解决您的用例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-21
    • 1970-01-01
    • 2012-10-27
    • 2012-11-09
    • 2021-09-25
    • 2020-03-22
    相关资源
    最近更新 更多