Python 可停止线程是否需要被守护进程或 .join()?
Does a Python Stoppable Thread needs to be Daemonized or be .join()?
当使用 class Pup
创建可停止的线程时,这些线程本应在后台 运行 直到调用 .stop()
:
如果在 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()
必须 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
应该 join
ed。
因为它只是 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.
- 仅当您的代码负责检查
stopper
标志并且随后从线程退出无法正常工作时,才有可能发生泄漏。否则,没有泄漏,因为应用程序,即使 join
没有被调用,也会等待所有非守护线程的完成。但是使用 join
可以更好地控制程序流程。
- 考虑到以上所有因素,我认为将
StoppableThread
设为 daemon
是个坏主意。
当使用 class Pup
创建可停止的线程时,这些线程本应在后台 运行 直到调用 .stop()
:
如果在
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()
必须
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
应该 join
ed。
因为它只是 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.
- 仅当您的代码负责检查
stopper
标志并且随后从线程退出无法正常工作时,才有可能发生泄漏。否则,没有泄漏,因为应用程序,即使join
没有被调用,也会等待所有非守护线程的完成。但是使用join
可以更好地控制程序流程。 - 考虑到以上所有因素,我认为将
StoppableThread
设为daemon
是个坏主意。