你以为多线程=快?别天真了!
Python 的 GIL(全局解释器锁)是绕不开的坎。
多线程在 CPU 密集型任务中几乎没用,因为同一时间只有一个线程能执行 Python 字节码。
看这段代码:
import threading
import time
defcpu_bound():
sum(i * i for i in range(10**6))
start = time.time()
threads = [threading.Thread(target=cpu_bound) for _ in range(4)]
[t.start() for t in threads]
[t.join() for t in threads]
print(f"多线程耗时: {time.time() - start:.2f}s")
结果?比单线程还慢!因为线程切换开销 + GIL 争抢。
异步就是万能药?醒醒吧!
async/await 不等于自动提速。
很多人把 asyncio 当成并发银弹,但如果你混用阻塞调用(比如 time.sleep() 或普通文件读写),整个事件循环就卡死了。
import asyncio
asyncdeffake_async():
time.sleep(1) # ❌ 阻塞!不是 await asyncio.sleep(1)
return"done"
asyncdefmain():
await asyncio.gather(fake_async(), fake_async())
asyncio.run(main()) # 实际耗时≈2秒,根本没并发!
记住:异步只对 I/O 密集型有效,且必须全程非阻塞。
第3个误区:疯狂开进程,CPU直接100%💥
以为 multiprocessing 越多越好?小心系统崩盘。
有人一激动,上来就开 100 个进程:
from multiprocessing import Process
defworker():
whileTrue:
pass# 空转!吃满一个核心
[Process(target=worker).start() for _ in range(100)]
后果?你的 CPU 温度飙升,风扇狂转,系统卡死。
正确做法:进程数 ≈ CPU 核心数(os.cpu_count())。
超了?只是徒增调度开销,性能反而下降。
锁用错了,程序比单线程还慢
加锁是为了安全,但滥用锁等于自废武功。
比如这个“经典”反面教材:
import threading
counter = 0
lock = threading.Lock()
defincrement():
global counter
for _ in range(100000):
with lock:
counter += 1# 锁粒度太大!
threads = [threading.Thread(target=increment) for _ in range(10)]
[t.start() for t in threads]
[t.join() for t in threads]
每次循环都抢锁,线程大部分时间在等。
优化:批量操作再加锁,或者用 queue、concurrent.futures 等更高层工具。
忽略资源限制,程序跑着跑着就挂了
并发不是无限的,内存和文件描述符会先爆。
比如用 ThreadPoolExecutor 开 10000 个线程:
from concurrent.futures import ThreadPoolExecutor
import requests
deffetch(url):
return requests.get(url)
with ThreadPoolExecutor(max_workers=10000) as executor:
futures = [executor.submit(fetch, "https://example.com") for _ in range(10000)]
结果?很可能 OSError: [Errno 24] Too many open files。
Linux 默认每个进程最多 1024 个文件描述符。
建议: 用连接池(如 httpx.AsyncClient)+ 合理控制并发数(通常 50~200 足够)。
并发不是魔法,而是权衡的艺术
真正的高手,懂得什么时候用线程、什么时候用进程、什么时候干脆别并发。
- CPU 密集 →
multiprocessing(但别超核数) - I/O 密集 →
asyncio 或 threading(注意非阻塞)
数据说话: 在 8 核机器上,处理 100 个 CPU 密集任务:
- 多进程(100 进程):≈6.8 秒(调度开销反噬)
所以,并发不是越多越好,而是刚刚好才最爽。
下次写并发代码前,先问自己:我在解决什么问题?瓶颈在哪?
别让第3个误区,把你电脑干冒烟了 😅