多线程
Python多线程编程指南
1. 线程基础
Python通过threading模块提供多线程支持。每个进程至少有一个主线程(MainThread),可以创建额外的子线程来执行并发任务。
1.1 创建线程
1.2 线程属性
threading.current_thread(): 获取当前线程实例threading.active_count(): 返回当前活跃线程数threading.enumerate(): 返回当前所有线程列表
2. 线程同步与锁
多线程共享进程内存空间,当多个线程修改同一变量时可能产生竞争条件。
2.1 竞争条件示例
2.2 使用Lock解决竞争
2.3 其他同步原语
threading.RLock: 可重入锁,同一线程可多次获取threading.Condition: 条件变量,用于线程间通信threading.Semaphore: 信号量,控制访问资源的线程数threading.Event: 事件对象,用于线程间简单通知
3. GIL(全局解释器锁)问题
Python的GIL是CPython解释器的实现细节,它导致:
- 任何时候只有一个线程在执行Python字节码
- I/O密集型任务仍可从多线程受益
- CPU密集型任务无法有效利用多核
3.1 处理GIL限制的方案
- 使用多进程:
multiprocessing模块绕过GIL限制 - 使用C扩展:在C扩展中释放GIL执行计算
- 使用其他解释器:如Jython或IronPython没有GIL
- 异步编程:
asyncio适合I/O密集型任务
4. 线程池与最佳实践
4.1 使用ThreadPoolExecutor
4.2 多线程编程最佳实践
- 避免共享状态:尽量使用线程局部数据
- 使用队列通信:
queue.Queue是线程安全的 - 适当使用锁:锁粒度要尽可能小
- 考虑线程安全:优先使用线程安全的数据结构
- 处理异常:线程中的异常不会传播到主线程
5. 线程局部数据
6. 多线程与多进程选择指南
7. 现代Python并发编程建议
- I/O密集型:考虑
asyncio或线程池 - CPU密集型:使用
multiprocessing或concurrent.futures.ProcessPoolExecutor - 混合型:结合多进程和多线程
- 复杂场景:考虑
celery等分布式任务队列
Python 3.10+提供了更强大的并发工具,如asyncio改进和新的concurrent.futures特性,开发者应根据具体需求选择合适的并发模型。

