Python多线程无法加速CPU密集型任务,因CPython的GIL强制单线程执行字节码;仅I/O密集型任务适用threading,CPU密集型必须用multiprocessing或ProcessPoolExecutor。
Python 的多线程在 CPU 密集型任务中基本不加速,这是由 GIL(全局解释器锁)决定的,不是写法或版本问题。
threading 无法提升 CPU 密集型任务性能CPython 解释器为保证内存管理安全,在同一时刻只允许一个线程执行 Python 字节码。GIL 是互斥锁,不是可配置开关,也无法通过多核绕过。
sum([x**2 for x in range(10**7)]))都受 GIL 限制threading.Thread
启动再多,CPU 使用率也不会超过单核 100%time.sleep()、requests.get()、文件读写)主动释放 GIL 时,其他线程才能运行threading,而不是 multiprocessing
适用场景非常明确:高并发 I/O 等待,且任务间无强状态共享需求。
threading + requests(每个请求阻塞时自动让出 GIL)threading 比 multiprocessing 启动快、内存开销小dict、list)且不涉及复杂同步 → threading 可直接引用,multiprocessing 需用 Manager 或 Queue
multiprocessing 在 Windows 上反复导入主模块的问题threading.Thread 启动后不执行?常见卡点最常被忽略的是没调用 start(),而是误调了 run() —— 后者只是普通函数调用,仍在主线程同步执行。
import threading import timedef worker(): time.sleep(1) print("done")
t = threading.Thread(target=worker) t.run() # ❌ 错误:同步执行,不启新线程
t.start() # ✅ 正确:异步启动线程
t.join() 导致主线程退出,子线程被强制终止(尤其脚本末尾无等待)lambda 传参时闭包陷阱:for i in range(3): Thread(target=lambda: print(i)) 会全打印 2,应写成 lambda i=i: print(i)
target 函数里捕获或重写 run()
multiprocessing 或 concurrent.futures.ProcessPoolExecutor
只要任务是 CPU 密集型(如图像处理、加密、科学计算),必须用进程而非线程。注意:
multiprocessing 中的函数必须能被序列化(不能是嵌套函数、lambda、类实例方法,除非用 functools.partial 包装)mmap 或 shared_memory(Python 3.8+)concurrent.futures.ProcessPoolExecutor 比裸用 multiprocessing.Process 更简洁,推荐作为默认选择多线程的“并发”和多进程的“并行”,底层机制完全不同;混淆这两者,是绝大多数性能问题的根源。