前言:本博文主要讲解Python中的GIL(全局解释器锁),本人经过查阅多个资料,摒弃一些较官方的描述,用自己的语言整理并加以补充,如果有描述有误的地方,还望读者在评论区指出,谢谢!

文章目录

  • 一、GIL是什么
  • 二、为什么会有GIL
  • 三、GIL的副作用
  • 四、GIL的总结
  • 五、GIL面试题

一、GIL是什么

GIL:又称全局解释器锁。作用就是限制多线程同时执行,保证同一时间内只有一个线程在执行。线程非独立的,所以同一进程里线程是数据共享,当各个线程访问数据资源时会出现“竞争”状态,即数据可能会同时被多个线程占用,造成数据混乱,这就是线程的不安全。所以引进了互斥锁,确保某段关键代码、共享数据只能由一个线程从头到尾完整地执行。

其次我们需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。有名的编译器例如GCC,INTEL C++,Visual C++等。Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行。像其中的JPython就没有GIL。然而因为CPython是大部分环境下默认的Python执行环境。所以在很多人的概念里CPython就是Python,也就想当然的把GIL归结为Python语言的缺陷。所以这里要先明确一点:GIL并不是Python的特性,Python完全可以不依赖于GIL。

那么在这里就反映出一个问题:在我们的Python语言中多线程其实是假的多线程,它只会在一个CPU上运行。这又是为什么呢?因为在Python上开启多个线程,由于GIL的存在,每个单独线程都会在竞争到GIL后才运行,这样就干预OS内部的进程(线程)调度,结果在多核CPU上:Python的多线程实际是串行执行的,并不会同一时间多个线程分布在多个CPU上运行。

二、为什么会有GIL

简单的来说:当初Python语言在设计的时候,市面上并没有多核CPU,因此线程都是单线程的。随着时间的推移、科技的发展,逐渐出现多核CPU,各CPU厂商在核心频率上的比赛已经被多核所取代,为了更有效的利用多核处理器的性能,就出现了多线程的编程方式,而随之带来的就是线程间数据一致性和状态同步的困难。

Python为了利用多核CPU,开始支持多线程。而解决多线程之间数据完整性和状态同步的最简单方法自然就是加锁,于是有了GIL这把超级大锁。因为有了GIL,所以我们的Python可以实现多进程,但是这是一个假的多进程,虽然它会利用多个CPU共同协作,但实则是利用一个CPU的资源。

但是这种GIL导致我们的多进程并不是真正的多进程,所以它的效率很低。但当大家试图去拆分和去除GIL的时候,发现大量库代码开发者已经重度依赖GIL而非常难以去除了。如果推到重来,多线程的问题依然还是要面对,但是至少会比目前GIL这种方式会更优雅。所以简单的说:GIL的存在更多的是历史原因。

三、GIL的副作用

Python的多线程在多核CPU上,只对于IO密集型计算产生正面效果;而当有至少有一个CPU密集型线程存在,那么多线程效率会由于GIL而大幅下降。正因为有了GIL的存在,我们Python的多线程效率才会比较低,毕竟它不是真正的多线程。那么此时,我们就可以考虑使用多进程去实现,因为多进程是可以利用多核的CPU资源的。但是又有一个问题?多进程需要的资源较大,明显不是最好的解决办法,那么如何高效的解决这一问题呢?

我们都知道Python它其实是一个“胶水”语言,它除了可以调用自己的模块。类库之外,还可以调用C、C++等语言的很多模块、类库。此时,我们只需加载动态库,把多进程这块,换成利用C语言去实现就可以了。

四、GIL的总结

  1. 因为GIL的存在,只有IO Bound场景下的多线程会得到较好的性能。
  2. 如果对并行计算性能较高的程序可以考虑把核心部分也成C模块,或者索性用其他语言实现。
  3. GIL在较长一段时间内将会继续存在,但是会不断对其进行改进。

五、GIL面试题

描述Python GIL的概念, 以及它对Python多线程的影响?编写一个多线程抓取网页的程序,并阐明多线程抓取程序是否可比单线程性能有提升,并解释原因。

Guido的声明:It isn’t Easy to Remove the GIL

he language doesn’t require the GIL – it’s only the CPython virtual machine that has historically been unable to shed it.

参考答案:

  1. Python语言和GIL没有任何关系。仅仅是由于历史原因在Cpython虚拟机(解释器),难以移除GIL。
  2. GIL:全局解释器锁。每个线程在执行的过程都需要先获取GIL,保证同一时刻只有一个线程可以执行代码。
  3. 线程释放GIL锁的情况: 在IO操作等可能会引起阻塞的system call之前,可以暂时释放GIL,但在执行完毕后,必须重新获取GIL Python 3.x使用计时器(执行时间达到阈值后,当前线程释放GIL)或Python 2.x,tickets计数达到100。
  4. Python使用多进程是可以利用多核的CPU资源的。
  5. 多线程爬取比单线程性能有提升,因为遇到IO阻塞会自动释放GIL锁。

深入理解Python中的GIL(全局解释器锁)相关推荐

  1. python gil 解除_详解Python中的GIL(全局解释器锁)详解及解决GIL的几种方案

    先看一道GIL面试题: 描述Python GIL的概念, 以及它对python多线程的影响?编写一个多线程抓取网页的程序,并阐明多线程抓取程序是否可比单线程性能有提升,并解释原因. GIL:又叫全局解 ...

  2. Python中的GIL(全局解释器锁)

    1. GIL全称Global Interpreter Lock,每个线程在执行的过程都需要先获取GIL,保证同一时刻只有一个线程可以执行代码. 2.GIL的缺点 GIL使Python不能充分利用多核心 ...

  3. python基础--GIL全局解释器锁、Event事件、信号量、死锁、递归锁

    ps:python解释器有很多种,最常见的就是C python解释器 GIL全局解释器锁: GIL本质上是一把互斥锁:将并发变成串行,牺牲效率保证了数据的安全 用来阻止同一个进程下的多个线程的同时执行 ...

  4. 【Python爬虫学习笔记11】Queue线程安全队列和GIL全局解释器锁

    Queue线程安全队列 在Python多线程编程中,虽然threading模块为我们提供了Lock类和Condition类借助锁机制来处理线程并发执行,但在实际开发中使用加锁和释放锁仍是一个经常性的且 ...

  5. Python高级——GIL全局解释器锁问题

    GIL全局解释器锁 GIL全局解释器锁是cpython解释器内部的一把锁,和python中的lock锁不是一个层面. GIL产生的背景:在cpython解释内部运行多个线程的时候,每个线程都需要解释器 ...

  6. Python GIL全局解释器锁

    目录 GIL全局解释器锁 一.引入: 二.GIL介绍 三.GIL与Lock 四.GIL与多线程 总结 GIL全局解释器锁 一.引入: 首先要明白,GIL并不是Python的一个特性,其实在我们通常所称 ...

  7. gil php,网络编程之多线程——GIL全局解释器锁

    网络编程之多线程--GIL全局解释器锁 一.引子 定义: In CPython, the global interpreter lock, or GIL, is a mutex that preven ...

  8. 并发服务器的信号传递,使服务器支持并发、GIL全局解释器锁、死锁和Rlock、信号量、event事件、...

    服务器的并发实现: 服务端: importsocketfrom threading importThread"""服务端 1.要有固定的IP和PORT 2.24小时不间断 ...

  9. 4,GIL全局解释器锁,event事件,信号量

    今日内容 1,GIL全局解释器锁 2,死锁 3,信号量 4,event事件 5,队列一:GIL全局解释器锁 什么是GIL 全局解释器锁: 它的本质也是一把互斥锁,是在CPython解释器锁,将并发变为 ...

  10. 深入理解Python中的GIL(全局解释器锁)。

    Python是门古老的语言,要想了解这门语言的多线程和多进程以及协程,以及明白什么时候应该用多线程,什么时候应该使用多进程或协程,我们不得不谈到的一个东西是Python中的GIL(全局解释器锁).这篇 ...

最新文章

  1. 2021 OceanBase 数据库大赛来了!
  2. androidstudio常见问题
  3. PHPExcel所遇到问题的知识点总结
  4. mysql 4 基础教程_MySQL基础教程(四):MySQL 管理
  5. MySQL 每秒57万的写入,带你飞呀!
  6. java基础--java.util.Date类型小结
  7. cordova splashscreen插件在android平台的使用
  8. 经典FOXMAIL报错 winsock error 11004
  9. leetcode讲解--559. Maximum Depth of N-ary Tree
  10. 摩托罗拉周二将正式分拆为两经营实体
  11. 中的实践 中兴_中兴通讯5G智慧治水业务在千岛湖畔下姜村成功实践
  12. 腾讯优图、AI Lab招聘计算机视觉算法工程师
  13. 软考网络工程师学习笔记3-广域通信网
  14. Python实验项目1例:使用进程池统计指定范围内素数的个数
  15. [转] 为你的项目选择一个合适的开源协议
  16. Android 的座位图控件,用于电影票等选座页面的 APP 中
  17. 常见图片存储格式文件简介
  18. My97datepicker时间控件的简单使用
  19. torch之optimizer.step() 和loss.backward()和scheduler.step()的关系与区别
  20. android 文件管理器下载,ES文件管理器下载

热门文章

  1. 跟领导碰面不知道该说什么,给你几个技巧来破冰?
  2. Wakeup linux system from sleep mode
  3. currentStyle与getComputedStyle的用法
  4. Jumpserver-堡垒机
  5. JumpServer堡垒机实践
  6. html给图片加描边,photoshop中如何给图片文字加描边
  7. 苹果nfc功能怎么开启_手机上面的NFC功能怎么用的
  8. Linux命令完全指南sysctl,Linux的Sysctl命令
  9. 玩游戏提示缺少d3d11.dll?
  10. 国内行业垂直型SaaS公司有哪些?发展前景如何?