Python 并发——基础

141 阅读2分钟

程序多线程并发

目的

  • 提高程序运行的速度

程序提速的方式

  1. 单线程串行
  2. 多线程并发
  3. 多 CPU 并行
  4. 多机器并行

python 运行效率低下原因

  1. 动态类语言,边解释边执行;

  2. 不需要定义数据类型,Python 判断数据类型也会降低执行效率

  3. GIL(global interpreter lock;全局解释器锁)

    GIL :序设计语言解释器用于同步线程的一种机制,使得任何时刻仅有一个线程在执行。即便在多核处理器上,使用 GIL 的解释器也值允许一同时一个时间执行一个线程。

如何规避 GIL 的限制

  1. 多线程机制依旧是有用的,用于 I/O 密集型计算,因为 I/O 期间线程会释放 GIL,实现 CPU 和 I/O 之间的并行,因此多线程用于 CPU 的密集型计算时,只会更加拖慢速度;
  2. 使用multiprocessing 的进程机制实现并行计算,利用多核 CPU 优势,因此对 GIL 问题,Python 提供了 multiprocessing

Python 对并发编程的支持

1. 多进程

porcess,multiprocessing

  • 一个进程中可以有多个线程,
  • 可用资源最多,但可以启动的数据比线程少
  • 适用于 CPU 密集型计算

2. 多线程

thread

  • 占用资源少
  • 相比进程:多线程只能并发执行,不能利用多 CPU(GIL)
  • 相比协程:启动数目有限,占用内存职员,有线程切换的开销
  • 适用于 I/O密集型,同时运行的任务数目不能太多

3. 多协程

coroutine,asyncio

  • 一个线程具有多个协程
  • 内存开销最小,启动协程数量最大
  • 支持的库有限(aiohttp vs request),代码实现复杂
  • 适用于 I/O 密集型,同时运行的任务数目可以很大

CPU 密集型计算 vs I/O 密集型计算

CPU 密集型:CPU-bound

  • 限速就是 CPU,CPU 需要大量计算和处理,CPU 占用率高
  • 压缩和解压缩、加密和解密、正则表达式搜索 IO 密集型:I/O-bound
  • CPU 占用率低
  • 文件处理程序、网络爬虫程序、读写数据库程序

4. 其他

  1. 异步 I/O
  2. 使用 lock 对资源加锁,房子冲突访问
  3. 使用 queue 实现对不同线程\进程之间的数据通信,实现生产者消费者模式
  4. 使用线程池\进程池,来简化线程\进程的任务提交,等待结果和获取结果
  5. 使用 subprocess 启动外部程序的进程,并进行输入输出交互