分享

python并发编程: Python速度慢的罪魁祸首,全局解释器锁GIL

 攻城狮成长日志 2023-10-13 发布于广东

往期文章:

  1. 并发编程简介
  2. 怎样选择多线程多进程多协程

python速度慢的两大原因

  • 动态类型语言,边解释边执行
  • 由于GIL,无法利用多核CPU并发执行

GIL是什么?

全局解释锁(Global Interpreter Lock,GIL)是计算机程序设计语言解释器用于同部线程的一种机制,它使得任何时刻仅有一个进程在执行。即使在多核心处理器上,使用GIL的解释器也只允许同一时间执行一个线程。

在上图中的流程:

  • 当线程1在运行的时候,则会启动GIL
  • 当线程1需要进行IO操作时,GIL则会释放,此时线程1切换到线程2运行,GIL再次启用。
  • 当线程2运行IO时,GIL再次释放,此时线程2切换到线程3,GIL则再次启用。

为什么有GIL这个东西?

为了解决多线程之间数据完整性和状态同步问题。举例子:Python中对象的管理,是使用引用计数器进行的,引用数为0则释放对象。开始:线程A和线程B都引用了对象obj,obj.ref_num = 2,线程A和B都想撤销对obj的引用

上图中线程A和线程B都引用了对象obj, 首先,线程A准备销毁obj引用,将计数器减1,刚减完,切换到了线程B, 线程B也要销毁obj引用,将计数器减1,然后判断引用等于0,则将其释放掉。当切换到线程A继续执行的时候,发现obj的引用已经无法获取计数器的值了。所以,就报错了。

怎么规避GIL带来的限制?

  • 多线程 threading 机制依然是有用的,用于IO密集型计算。因为在 I/O (read,write,send,recv,etc.)期间,线程会释放GIL,实现CPU和IO的并行。因此多线程用于IO密集型计算依然可以大幅提升速度。但是多线程用于CPU密集型计算时,只会更加拖慢速度

  • 使用multiprocessing的多进程机制实现并行计算、利用多核CPU优势。为了应对GIL的问题,Python提供了multiprocessing

总结

  • 多线程适用于IO密集型问题,当线程在处理IO问题时,将释放GIL锁,并切换至下一线程,线程的切换使用的是CPU,线程的处理使用的是IO,这样就实现了CPU和IO的并行。
  • 多进程用于处理CPU密集性问题,适用于充分发挥多核CPU的优势,多进程其实变相的解决了GIL锁的弊端。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多