1. 为什么需要并发编程?
现代计算机普遍配备多核CPU,但默认情况下Python程序只会使用其中一个核心。这就好比餐厅有8个厨师(CPU核心),但老板只让1个人干活,其他7个都在摸鱼。当我们需要处理I/O密集型任务(如网络请求)或计算密集型任务(如数据分析)时,这种单线程模式会造成严重的资源浪费。
我在处理一个爬虫项目时就深有体会:单线程爬取1000个网页需要2小时,而改用多线程后仅需15分钟。但并发编程不是银弹,错误的使用会导致:
- 数据竞争(Data Race)
- 死锁(Deadlock)
- GIL性能陷阱
- 调试难度指数级上升
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 多线程:I/O密集型的首选方案
2.1 线程的本质与GIL机制
Python线程是操作系统原生线程的封装,但受到全局解释器锁(GIL)的限制。可以把GIL想象成公司唯一的一把会议室钥匙:
- 任何时候只有一个线程能拿到钥匙执行字节码
- 遇到I/O操作时会主动释放钥匙
- CPU密集型操作会一直霸占钥匙
这种机制导致纯计算任务使用多线程反而更慢。但在网络爬虫、文件处理等I/O等待占95%以上的场景中,多线程能大幅提升吞吐量。
2.2 实战:线程池最佳实践
直接创建裸线程是新手常见错误,正确做法是使用concurrent.futures线程池:
python复制from concurrent.futures import ThreadPoolExecutor
import requests
def fetch(url):
return requests.get(url).status_code
urls = ['https://example.com' for _ in range(100)]
# 推荐写法
with ThreadPoolExecutor(max_workers=10) as executor:
results = list(executor.map(fetch, urls))
关键参数经验值:
- I/O密集型:worker数量 = min(32, os.cpu_count() + 4)
- 数据库操作:不超过连接池最大连接数
- 超时设置:总超时+单任务超时双重保险
2.3 线程安全防护手册
共享数据时务必
