Python主线程结束后子线程未立即终止的原因探究
Python子线程未随主线程终止的原因解析
示例代码
import time import threading class foo: def __init__(self): self.run_bar = True def entry(self): t_bar = threading.Thread(target=self.bar, name="bar") t_bar.start() if t_bar.is_alive(): self.run_bar = False def bar(self): while self.run_bar: print("1") time.sleep(2) print("2") print("3") f = foo() f.entry() print("Entry finished")
预期输出
1 Entry finished
实际输出
1 Entry finished 2 3
用户疑问
是否是因为bar方法引用了foo类的成员,导致子线程被自动join,主线程未直接终止以避免实例f被垃圾回收?
解答
不是你猜测的原因,核心问题出在线程执行时序和Python非守护线程的默认行为上:
- 主线程启动子线程后,子线程立刻执行
bar方法,打印"1"后进入2秒的休眠;与此同时主线程快速完成entry方法内的剩余逻辑,把self.run_bar设为False,接着输出"Entry finished"。 - 子线程的
while循环判断是在每轮循环开始时执行的,它已经进入了循环体内部,所以即使self.run_bar已经被改为False,当前循环体内的print("2")和print("3")还是会执行完毕。 - 另外,Python默认创建的是非守护线程,主线程结束时会等待所有非守护线程执行完成后,才会终止整个程序。这就是为什么子线程能完成剩余代码输出的关键。如果想要主线程退出时直接终止子线程,可以在启动子线程前添加
t_bar.daemon = True,这样就能得到你预期的输出。
内容的提问来源于stack exchange,提问作者yankovs
相关产品推荐
相关产品推荐

