为何Python等待线程的while循环无print时比有print时运行更慢
问题原因
核心是CPython的全局解释器锁(GIL)调度规则和空忙等循环的特性共同导致的:
- 无
print的空循环属于纯CPU密集型忙等待:CPython默认只有当线程执行IO操作、或者执行满预设数量的字节码(默认阈值为1000)时,才会释放GIL给其他线程调度。你写的空while循环每次仅执行threading.active_count()读取和数值比较,都是耗时极短的纯CPU操作,短时间内就能执行大量字节码,几乎全程抢占GIL不释放,导致端口扫描的工作线程很难抢到GIL执行任务,只能频繁等待调度,整体耗时自然大幅拉长到128秒。 - 添加
print后触发GIL主动释放:print()属于标准输出IO操作,只要线程执行IO类操作,就会主动让出GIL,此时你的扫描工作线程就能正常拿到GIL推进任务,整体耗时就回归到符合预期的26秒。
正确实现方式
不要用忙等待的方式等待线程结束,推荐在启动线程时将所有线程对象存入列表,后续逐个调用join()方法等待线程执行完毕,既不会浪费CPU资源,也不会出现GIL抢占问题,示例逻辑如下:
import threading # 启动线程时存入列表 thread_list = [] for i in range(100): t = threading.Thread(target=你的扫描函数) t.start() thread_list.append(t) # 等待所有线程执行完毕 for t in thread_list: t.join() # 后续逻辑 print("扫描结束")
内容的提问来源于stack exchange,提问作者Andrew Duskin
相关产品推荐
相关产品推荐

