Python 并发编程
并发编程介绍
程序提速的方法: 单线程串行、多线程并发、多 CPU 并行、多机器并行。
| Python |
|---|
| # 多线程:threading,利用CPU和IO可以同时执行的原理,让CPU不会干巴巴等待IO完成
# 多进程:multiprocessing,利用多核CPU能力,真正的并行执行任务
# 异步IO:asyncio,在单线程利用CPU和IO同时执行的原理,实现函数异步执行
# 使用Lock对资源加锁,防止冲突访问
# 使用Queue实现不同线程/进程之间的数据通信,实现生产者-消费者模式
# 使用线程池/进程池pool,简化线程/进程的任务提交,等待结束,获取结果
# 使用subprocess启动外部程序的进程,并进行输入输出交互
|
并发编程选择
Python 并发编程: 多线程(thread)多进程(process)多协程(coroutine)之间的选择。
| Python |
|---|
| # CPU密集型计算(CPU-bound):也叫计算密集型,是指IO在很短的时间就完成了,CPU需要大量的计算和处理,特点是CPU占用率非常高,例如:压缩解压缩、加密解密、正则表达式搜索
# IO密集型计算(IO-bound):系统运行的大部分状况是CPU在等IO(磁盘/硬盘)的读写操作,CPU占用率仍然很低,例如:文件处理程序、网络爬虫程序、读写数据库程序
|
| Python |
|---|
| # 多进程process(multiprocessing):
# 优点:可以利用多核CPU并行运算
# 缺点:占用资源最多、可启动数目比线程少
# 适用于:CPU密集型计算
## 一个进程中可以启动N个线程
# 多线程thread(threading)
# 优点:相对进程,更轻量级、占用资源少
# 缺点:
# 相比进程:多线程只能并发执行,不能利用多个CPU(GIL)
# 相比协程:启动树木有限制,占用资源,有线程切换开销
# 适用于:IO密集型计算、同时运行任务数目要求不多
## 一个线程可以启动N个协程
# 多协程coroutine(asyncio)
# 优点:内存开销最小,启动协程数量多
# 缺点:支持的库有限制,代码实现复杂
# 适用于:IO密集型计算、超多任务运行,但要有现成的库支持
|
全局解释器锁 GIL
Python 速度慢的原因:
- 动态类型语言,边解释边执行。
- 存在全局解释器锁 CIL,无法利用多核 CPU 并发执行。
CIL: 全局解释器锁,计算机程序设计语言解释器用于同步线程的一种机制,他使得任何时刻仅有一个线程在执行。即便在多核心处理器上,使用 GIL 的解释器也只允许同一时间执行一个线程。

多线程 threading 机制依然是有用的,用于 IO 密集型计算,因为在 IO 期间,线程会释放 GIL,实现 CPU 和 IO 的并行,因此,多线程用于 IO 的密集型计算依然可以大幅度提高速度,但是多线程执行 CPU 密集型计算,只会更加拖慢速度;
多进程 mutiprocessing 的多进程机制实现并行计算,利用多核 CPU 优势,用于解决 GIL 问题。