Python线程执行完成后仍处于存活状态的原因排查
问题描述
我在练习实现非阻塞自定义线程池(同时在了解concurrent.futures),但遇到一个问题:线程执行完成后,代码里始终显示线程处于存活状态。以下是复现代码和运行输出,请帮忙解释原因。
import threading import time class myThread (threading.Thread): def __init__(self, num): threading.Thread.__init__(self) self.num = num + 1 def run(self): print(f">>> {self.name} is starting") time.sleep(self.num*2.0) print(f"<<< {self.name} is finishing") num_threads = 3 threads = [] for i in range(num_threads): t = myThread(i) t.start() threads.append(t) num_finished_threads = 0 while num_finished_threads < num_threads: time.sleep(0.5) for t in threads: if t.is_alive: print(f"{t.name} is alive") else: t.join() num_finished_threads += 1
运行输出:
>>> Thread-1 is starting >>> Thread-2 is starting >>> Thread-3 is starting Thread-1 is alive Thread-2 is alive Thread-3 is alive Thread-1 is alive Thread-2 is alive Thread-3 is alive Thread-1 is alive Thread-2 is alive Thread-3 is alive <<< Thread-1 is finishing Thread-1 is alive Thread-2 is alive Thread-3 is alive Thread-1 is alive Thread-2 is alive Thread-3 is alive Thread-1 is alive Thread-2 is alive Thread-3 is alive Thread-1 is alive Thread-2 is alive Thread-3 is alive <<< Thread-2 is finishing Thread-1 is alive Thread-2 is alive Thread-3 is alive Thread-1 is alive Thread-2 is alive Thread-3 is alive Thread-1 is alive Thread-2 is alive Thread-3 is alive Thread-1 is alive Thread-2 is alive Thread-3 is alive <<< Thread-3 is finishing Thread-1 is alive Thread-2 is alive Thread-3 is alive
问题原因分析
核心错误是你把线程的is_alive方法当成了属性来使用:
t.is_alive是一个方法对象,只要这个方法存在,条件判断就会返回True,完全不考虑线程实际的存活状态。- 正确的用法应该是调用这个方法:
t.is_alive(),它会返回布尔值来表示线程当前是否存活。
因为这个错误,你的代码永远不会进入else分支,num_finished_threads永远不会递增,循环会一直执行;同时线程结束后也不会被调用join(),但本质上线程已经结束了,只是你的判断逻辑错误导致误以为它还处于存活状态。
修正后的代码
import threading import time class myThread (threading.Thread): def __init__(self, num): threading.Thread.__init__(self) self.num = num + 1 def run(self): print(f">>> {self.name} is starting") time.sleep(self.num*2.0) print(f"<<< {self.name} is finishing") num_threads = 3 threads = [] for i in range(num_threads): t = myThread(i) t.start() threads.append(t) num_finished_threads = 0 while num_finished_threads < num_threads: time.sleep(0.5) for t in threads: if t.is_alive(): # 改为调用is_alive方法 print(f"{t.name} is alive") else: t.join() num_finished_threads += 1
内容的提问来源于stack exchange,提问作者DuGNu
相关产品推荐
相关产品推荐

