Cpython解释器中的GIL全局解释器锁


Posted in Python onNovember 09, 2020

1、什么是GIL全局解释器锁

GIL:Global Interpreter Lock,意思就是全局解释器锁,这个GIL并不是Python的特性,他是只在Cpython解释器里引入的一个概念,而在其他的语言编写的解释器里就没有GIL,例如:Jython,Pypy等

下面是官方给出的解释:

In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython's memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)

翻译过来的意思就是:在CPython中,全局解释器锁(GIL)是一个互斥锁,可以防止多个本地线程同时执行Python字节码。这个锁是必要的,主要是因为CPython的内存管理不是线程安全的。(但是,由于GIL存在,其他特性已经发展到依赖于它所执行的保证。)

所以:

GIL本质上就是一把互斥锁,用来保证数据的正确性,使数据可以正常同步。

GIL就像是BUG一般存在的全局互斥锁,目前无法通过代码去除GIL

结论:在CPython解释器中,在同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势

PS:我们平常所使用的python是C语言编写的,所以大部分人所说的python也指CPython,CPython是python的官方版本,若是指其他语言写的python,一般情况下会指明,如Jypthon、Pypy等

2、为什么会出现GIL

随着电脑多核CPU的出现,python为了充分利用多核CPU,进行多线程的编程方式便普及了起来,但是随之而来的困难是线程之间数据的一致性和状态同步,python为了解决这个数据不能同步的问题,所以设计了GIL全局解释器锁,其实就是互斥锁

说到互斥锁,在多线程互斥锁中共享全局变量的时候会有线程对全局变量进行的资源竞争,会对全局变量的修改产生不是我们想要的结果,而那个时候用到的是python中线程模块里面的互斥锁。

如下例(未加线程互斥锁):

from threading import Threadimport time


n = 100
def task():
  global n
  m = n
  time.sleep(0.5)  # 模拟IO操作
  n = m - 1


if __name__ == '__main__':
  list1 = []
  for i in range(10):
    t = Thread(target=task)
    t.start()
    list1.append(t)

  for t in list1:
    t.join()

  print(n)

 执行结果:

99

在上面的例子里,我创建了10个线程来争夺对 n 进行 -1 操作,但是结果并非我想要的,所以我在这里加入了互斥锁

如下例(加线程互斥锁):

from threading import Thread
from threading import Lock
import time


n = 100
def task(lock):
  global n
  lock.acquire()  # 加锁
  m = n
  time.sleep(0.5)  # 模拟IO操作
  n = m - 1
  lock.release()  # 解锁


if __name__ == '__main__':
  list1 = []
  lock = Lock()
  for i in range(10):
    t = Thread(target=task, args=(lock, ))
    t.start()
    list1.append(t)

  for t in list1:
    t.join()

  print(n)

执行结果:

90

这次就可以得到我想要的结果

3、GIL的优缺点

优点:

保证数据的正确性

缺点:

单个进程下,开启多个线程,牺牲了执行效率,无法实现并行,只能实现并发

4、如何体现GIL全局解释器锁

在Cpython解释器中,当python代码有一个线程开始访问解释器的时候,GIL会把这个大锁给锁上,此时此刻其他的线程只能干等着,无法对解释器的资源进行访问,这一点就和互斥锁相似。而只是这个过程发生在我们的Cpython中,同时也需要等这个线程分配的时间到了,这个线程把GIL释放掉,类似互斥锁的lock.release()一样,另外其他的线程才开始跑起来。

Cpython解释器中的GIL全局解释器锁

以上就是Cpython解释器中的GIL全局解释器锁的详细内容,更多关于GIL全局解释器锁的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python之wxPython菜单使用详解
Sep 28 Python
Python金融数据可视化汇总
Nov 17 Python
python语言中with as的用法使用详解
Feb 23 Python
Python实现朴素贝叶斯分类器的方法详解
Jul 04 Python
django缓存配置的几种方法详解
Jul 16 Python
浅谈Python基础—判断和循环
Mar 22 Python
python操作openpyxl导出Excel 设置单元格格式及合并处理代码实例
Aug 27 Python
Django密码存储策略分析
Jan 09 Python
Tensorflow:转置函数 transpose的使用详解
Feb 11 Python
python实现邮件循环自动发件功能
Sep 11 Python
Python在centos7.6上安装python3.9的详细教程(默认python版本为2.7.5)
Oct 15 Python
python 开心网和豆瓣日记爬取的小爬虫
May 29 Python
OpenCV实现机器人对物体进行移动跟随的方法实例
Nov 09 #Python
基于python爬取梨视频实现过程解析
Nov 09 #Python
Python eval函数介绍及用法
Nov 09 #Python
python tkinter的消息框模块(messagebox,simpledialog)
Nov 07 #Python
python 用struct模块解决黏包问题
Nov 07 #Python
python hmac模块验证客户端的合法性
Nov 07 #Python
python如何利用paramiko执行服务器命令
Nov 07 #Python
You might like
PHP分页详细讲解(有实例)
2013/10/30 PHP
thinkphp查询,3.X 5.0方法(亲试可行)
2017/06/17 PHP
php curl优化下载微信头像的方法总结
2018/09/07 PHP
PHP7 参数处理机制修改
2021/03/09 PHP
漂亮的仿flash菜单,来自蓝色经典
2006/06/26 Javascript
JQuery textlimit 显示用户输入的字符数 限制用户输入的字符数
2009/05/14 Javascript
js读取被点击次数的简单实例(从数据库中读取)
2014/03/07 Javascript
jquery 中ajax执行的优先级
2015/06/22 Javascript
JS实现获取键盘按下的按键并显示在页面上的方法
2015/11/04 Javascript
如何使用jquery easyui创建标签组件
2015/11/18 Javascript
jQuery文字提示与图片提示效果实现方法
2016/07/04 Javascript
基于jQuery代码实现圆形菜单展开收缩效果
2017/02/13 Javascript
js实现瀑布流效果(自动生成新的内容)
2017/03/16 Javascript
vue中子组件调用兄弟组件方法
2018/07/06 Javascript
深入Vue-Router路由嵌套理解
2018/08/13 Javascript
微信小程序实现顶部下拉菜单栏
2018/11/04 Javascript
解决vue移动端适配问题
2018/12/12 Javascript
详解使用React.memo()来优化函数组件的性能
2019/03/19 Javascript
王纯业的Python学习笔记 下载
2007/02/10 Python
python使用PyFetion来发送短信的例子
2014/04/22 Python
Python使用pygame模块编写俄罗斯方块游戏的代码实例
2015/12/08 Python
Python实现简单的文件传输与MySQL备份的脚本分享
2016/01/03 Python
Python WXPY实现微信监控报警功能的代码
2017/10/20 Python
python微信跳一跳系列之自动计算跳一跳距离
2018/02/26 Python
python实现log日志的示例代码
2018/04/28 Python
Python 确定多项式拟合/回归的阶数实例
2018/12/29 Python
python实现转盘效果 python实现轮盘抽奖游戏
2019/01/22 Python
python单线程下实现多个socket并发过程详解
2019/07/27 Python
PyQt5多线程刷新界面防假死示例
2019/12/13 Python
django使用channels实现通信的示例
2020/10/19 Python
html5小技巧之通过document.head获取head元素
2014/06/04 HTML / CSS
法院实习人员自我鉴定
2013/09/26 职场文书
开展批评与自我批评发言材料
2014/05/15 职场文书
地下停车场租赁协议范本
2014/10/07 职场文书
房屋质量投诉书
2015/07/02 职场文书
文明礼仪主题班会
2015/08/13 职场文书