Python多线程适合I/O密集型任务,因I/O时会释放GIL;不适合CPU密集型计算,因GIL限制导致性能不升反降;应依场景选用ThreadPoolExecutor、ProcessPoolExecutor或asyncio。
CPython 的 GIL(全局解释器锁)让多线程无法真正并行执行 CPU 密集型代码,但对 I/O 操作(如网络请求、文件读写、数据库查询)完全有效——因为 I/O 期间线程会主动释放 GIL,让其他线程运行。
常见适用场景包括:
requests.get 或 urllib.request.urlopen)open(...).read())用 threading 做数值计算、图像处理、加密解密等,性能通常不如单线程,甚至更慢——因为线程切换开销 + GIL 争抢。
验证方法很简单:
threading.Thread 启 4 个线程、multiprocessing.Process 启 4 个进程跑一遍time.perf_counter() 测耗时:多线程版本基本和单线程持平或略差;多进程明显更快遇到“既要并发又要算得快”的需求,优先考虑:
concurrent.futures.ThreadPoolExecutor,简洁可控multiprocessing 或 concurrent.futures.ProcessPoolExecutor
asyncio + aiohttp / aiomysql,资源占用更低dict 或 list,改用 queue.Queue 或加 threading.Lock
很多人以为“没显式改全局变量就没事”,其实很多内置操作不是原子的:
counter += 1 看似一行,实际分“读-算-写”三步,多线程下会丢数据my_list.append(x) 在特定压力下也可能出错(虽然概率低,但生产环境不能赌)logging.info() 是线程安全的,但自定义 handler 若操作共享文件或缓存,就得自己加锁最稳妥的做法:所有跨线程访问的可变对象,统一用 threading.Lock 包裹临界区,或者直接换用线程安全的数据结构(如 queue.Queue、threading.local)。