Python 可停止线程是否需要被守护进程或 .join()?

Does a Python Stoppable Thread needs to be Daemonized or be .join()?

当使用 class Pup 创建可停止的线程时,这些线程本应在后台 运行 直到调用 .stop()

  1. 如果在 pup.stop() 之后没有调用 pup.join() 会怎样?以下是否会导致泄漏:

    pup = Pup()
    pup.start()
    time.sleep(5)
    pup.stop()
    
    pup2 = Pup()
    pup2.start()
    time.sleep(5)
    pup2.stop()
    
    pup3 = Pup()
    pup3.start()
    time.sleep(5)
    pup3.stop()
    
  2. 必须 pup 是守护线程,因为我们 运行 它在后台?

以下主要代码借鉴自

import time
import threading

class StoppableThread(threading.Thread):
    """Thread class with a stop() method. The thread itself has to check
    regularly for the stopped() condition."""

    def __init__(self, *args, **kwargs):
        super(StoppableThread, self).__init__(*args, **kwargs)
        self._stopper = threading.Event()

    def stop(self):
        self._stopper.set()

    def stopped(self):
        return self._stopper.isSet()


class Pup(StoppableThread):
    def __init__(self, i, *args, **kwargs):
        super(Pup, self).__init__(*args, **kwargs)
        self.i = i

    def run(self):
        while True:
            if self.stopped():
                return
            print("Hello, world!", i)
            time.sleep(1)

for i in range(100):
    pup = Pup(i)
    pup.start()
    time.sleep(5)
    pup.stop()

StoppableThread 应该 joined。

因为它只是 threading.Thread 的薄包装,让您可以设置和检查标志 stopper

在这种情况下,必须有一个代码定期检查这个标志。检查之间的延迟量取决于 class 的用户。 并且假设线程应该被正确停止,你必须使用 join。因为如果您将线程设置为 daemon 并尝试在应用程序完成之前停止它:

Daemon threads are abruptly stopped at shutdown. Their resources (such as open files, database transactions, etc.) may not be released properly. If you want your threads to stop gracefully, make them non-daemonic and use a suitable signalling mechanism such as an Event.

  1. 仅当您的代码负责检查 stopper 标志并且随后从线程退出无法正常工作时,才有可能发生泄漏。否则,没有泄漏,因为应用程序,即使 join 没有被调用,也会等待所有非守护线程的完成。但是使用 join 可以更好地控制程序流程。
  2. 考虑到以上所有因素,我认为将 StoppableThread 设为 daemon 是个坏主意。