python中GIL的原理及用法总结

 更新时间:2021年03月08日 08:25:22   作者:小妮浅浅  
在本篇文章里小编给大家整理的是一篇关于python中GIL的原理及用法总结内容,有需要的朋友们可以学习参考下。

1、说明

GIL规定一个Python解释程序只能同时由一个线程控制。

在CPU限制类型和多线程代码中,GIL是一个性能瓶颈。

GIL使Python多线程成为伪并行多线程。

仅CPython解释器上存在GIL。

2、原理

(1)线程1、2、3轮流执行,每一个线程在执行是,都会锁住GIL,以阻止别的线程执行;

同样的,每一个线程执行一段后,会释放GIL,以允许别的线程开始利用资源。

(2)由于古老GIL机制,如果线程2需要在CPU2上执行,它需要先等待在CPU1上执行的线程1释放GIL(记住:GIL是全局的)

(3)如果线程1是因为 i/o 阻塞让出的GIL,那么线程2必定拿到GIL。但如果线程1是因为timer ticks计数满100ticks(大概对应了1000个bytecodes)让出GIL,那么这个时候线程1和线程2公平竞争。

(4)但要命的是,在Python 2.x, 线程1不会动态的调整自身的优先级,所以很大概率下次被选中执行的还是线程1,在很多个这样的选举周期内,线程2只能安静的看着线程1拿着GIL在CPU 1上欢快的执行。

(5)极端一点的情况下,比如线程1使用了while True在CPU1上执行,那就真是“一核有难,八核围观”了。

知识点扩展:

GIL设计理念与限制

python的代码执行由python虚拟机(也叫解释器主循环,CPython版本)来控制,python在设计之初就考虑到在解释器的主循环中,同时只有一个线程在运行。即在任意时刻只有一个线程在解释器中运行。对python虚拟机访问的控制由全局解释锁GIL控制,正是这个锁来控制同一时刻只有一个线程能够运行。

在调用外部代码(如C、C++扩展函数)的时候,GIL将会被锁定,直到这个函数结束为止(由于期间没有python的字节码运行,所以不会做线程切换)。

在python中使用都是操作系统级别的线程,linux中使用的pthread,window使用的是其原生线程。

从上面的概述中可以直观的看出py在同一时刻只能跑一个线程,这样在跑多线程的情况下,只有当线程获取到全局解释器锁后才能运行,而全局解释器锁只有一个,因此即使在多核的情况下也只能发挥出单核的功能。

那么这样看起来py不给力啊,GIL直接导致CPython不能利用物理多核的性能加速运行。那么为什么会有这样的设计?考虑到Guido van Rossum 在创造python的时候,上世纪90年代,多核cpu完全属于不可想象的,现在由于硬件发展速度太快,程序编写就要考虑用尽cpu的全部性能,否则就要被淘汰,那么对于python同样也要如此。

上面主要说的是这种设计的劣势,下面再讨论它的优势。

GIL的设计简化了CPython的实现,使得对象模型,包括关键的内建类型如字典,都隐式可以并发访问。锁住全局解释器使得其比较容易的实现对多线程的支持,但也折损了多处理器主机的并行计算能力。

但是不论标准的,还是第三方的扩展模块,都被设计成在进行密集计算任务时释放GIL。另外还有在做IO操作时,GIL总是被释放。对所有面对内建的操作系统C代码的程序来说,GIL会在这个IO调用之前被释放,以允许其它的线程在等待这个IO的时候运行。如果是纯计算的程序,没有IO操作,解释器会每隔100次或每隔一定时间15ms去释放GIL。

这里可以理解为IO密集型的python比计算密集型的程序更能利用多线程环境带来的便利。

到此这篇关于python中GIL的原理及用法总结的文章就介绍到这了,更多相关python中GIL的原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python分析微信好友性别比例和省份城市分布比例的方法示例【基于itchat模块】

    Python分析微信好友性别比例和省份城市分布比例的方法示例【基于itchat模块】

    这篇文章主要介绍了Python分析微信好友性别比例和省份城市分布比例的方法,结合实例形式分析了Python基于itchat模块获取及计算微信好友相关信息操作技巧,需要的朋友可以参考下
    2020-05-05
  • PyTorch 中的 torch.utils.data 解析(推荐)

    PyTorch 中的 torch.utils.data 解析(推荐)

    这篇文章主要介绍了PyTorch torch.utils.data.Dataset概述案例详解,主要介绍对 torch.utils.data.Dataset 的理解,需要的朋友可以参考下
    2023-02-02
  • Python的Django框架中使用SQLAlchemy操作数据库的教程

    Python的Django框架中使用SQLAlchemy操作数据库的教程

    SQLAlchemy是Python一个专门的数据库管理工具,如果对Django ORM觉得有些生疏的话完全可以结合SQLAlchemy,这里我们就来总结一下Python的Django框架中使用SQLAlchemy操作数据库的教程
    2016-06-06
  • Python OpenCV 使用滑动条来调整函数参数的方法

    Python OpenCV 使用滑动条来调整函数参数的方法

    这篇文章主要介绍了Python OpenCV 使用滑动条来调整函数参数的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • Numpy中np.dot与np.matmul的区别详解

    Numpy中np.dot与np.matmul的区别详解

    本文主要介绍了Numpy中np.dot与np.matmul的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • tensorflow实现加载mnist数据集

    tensorflow实现加载mnist数据集

    这篇文章主要为大家详细介绍了tensorflow实现加载mnist数据集,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-09-09
  • python中urllib模块用法实例详解

    python中urllib模块用法实例详解

    这篇文章主要介绍了python中urllib模块用法,以实例形式详细分析了python中urllib模块代替PHP的curl操作方法,具有不错的借鉴价值,需要的朋友可以参考下
    2014-11-11
  • Python中的正则表达式与JSON数据交换格式

    Python中的正则表达式与JSON数据交换格式

    正则表达式 是一个特殊的字符序列,一个字符串是否与我们所设定的这样的字符序列,相匹配快速检索文本、实现替换文本的操作。这篇文章主要介绍了Python中的正则表达式与JSON ,需要的朋友可以参考下
    2019-07-07
  • Python在groupby分组后提取指定位置记录方法

    Python在groupby分组后提取指定位置记录方法

    下面小编就为大家分享一篇Python在groupby分组后提取指定位置记录方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-04-04
  • Python urlopen()函数 示例分享

    Python urlopen()函数 示例分享

    urlopen(url, data=None, proxies=None) 即创建一个表示远程url的类文件对象,然后像本地文件一样操作这个类文件对象来获取远程数据。参数url表示远程数据的路径,一般是网址;参数data表示以post方式提交到url的数据;参数proxies用于设置代理。
    2014-06-06

最新评论