Python:检测名为exit()的父线程

Python:检测名为exit()的父线程,python,multithreading,Python,Multithreading,我有一个在后台运行的线程,可以从主线程进行更新: 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 = Qu

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

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()方法。

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

因此,您可以在构造函数中默认设置为
daemon=True
,或者在
start

ta = TestAnimation(1)
ta.daemon = True
ta.start()
编辑因为需要清理螺纹。 您可以使用和的组合来向守护进程线程发送信号,以便在退出之前进行清理

下面是一个简单的示例:

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')
演示:
由于
atexit
应该在退出时运行注册的函数,因此无需跟踪每个退出点来清理线程

好的,但是后台线程如何检测到主线程正在退出,以便它能够清理事情呢?@Passiday不确定还有什么比您已经在做的事情更简单的事情。你的方法有什么问题?(也许可以根据答案进行改进)@Passiday:您可以使用一个全局变量(可能与
锁一起使用以防止并发访问),并让线程定期检查它。另一种选择是使用
队列
发送“退出”消息。当我看到主线程exit()没有杀死后台线程时,我希望它能在线程中被检测到。我只是不想在主线程可能退出的每个点显式地调用停止线程。我更希望线程能够自己完成优雅的停止。@Passiday使用
threading.Event
atexit
更新了答案,以解决您的用例。
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.