python中GIL的原理及用法总结

作者:小妮浅浅 时间:2023-03-11 07:43:13 

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比计算密集型的程序更能利用多线程环境带来的便利。

来源:https://www.py.cn/jishu/jichu/27435.html

标签:python,GIL
0
投稿

猜你喜欢

  • python中利用xml.dom模块解析xml的方法教程

    2022-08-17 01:44:47
  • 浅谈python中频繁的print到底能浪费多长时间

    2022-01-31 06:24:34
  • php实现的三个常用加密解密功能函数示例

    2023-07-20 06:25:52
  • python实现守护进程、守护线程、守护非守护并行

    2021-02-03 09:06:56
  • PyTorch中torch.utils.data.DataLoader简单介绍与使用方法

    2023-10-30 07:12:00
  • 详解Python+Selenium+ChromeDriver的配置和问题解决

    2023-06-08 12:50:23
  • 页面包含的处理

    2024-05-09 09:04:18
  • python之PyAutoGui教你做个自动脚本计算器的方法

    2022-01-08 15:24:55
  • APAP ALV进阶写法及优化详解

    2023-11-21 19:41:07
  • 使用Django和Python创建Json response的方法

    2022-04-28 13:08:42
  • 关于Python中*args和**kwargs的深入理解

    2021-04-07 17:45:06
  • 用Dreamweaver MX实现网站批量更新

    2009-09-13 18:39:00
  • Python基于回溯法子集树模板实现8皇后问题

    2023-09-25 08:34:45
  • Python-typing: 类型标注与支持 Any类型详解

    2023-10-15 19:40:43
  • CentOS下安装python3.5+scrapy的方法步骤

    2022-07-17 20:01:42
  • 元素层叠级别及z-index剖析

    2008-07-22 12:03:00
  • Python列表计数及插入实例

    2023-05-26 23:41:12
  • Javascript中的getUTCDay()方法使用详解

    2024-05-11 10:24:24
  • python实现发送带附件的邮件代码分享

    2021-11-24 12:28:30
  • javascript管中窥豹 形参与实参浅析

    2024-04-16 09:25:54
  • asp之家 网络编程 m.aspxhome.com