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求crc32值的方法
Oct 05 Python
使用graphics.py实现2048小游戏
Mar 10 Python
浅谈python中的变量默认是什么类型
Sep 11 Python
python解决网站的反爬虫策略总结
Oct 26 Python
使用Python绘制图表大全总结
Feb 11 Python
PyQt实现界面翻转切换效果
Apr 20 Python
Python pip 安装与使用(安装、更新、删除)
Oct 06 Python
python将四元数变换为旋转矩阵的实例
Dec 04 Python
利用matplotlib实现根据实时数据动态更新图形
Dec 13 Python
如何在Win10系统使用Python3连接Hive
Oct 15 Python
4款Python 类型检查工具,你选择哪个呢?
Oct 30 Python
用python制作个视频下载器
Feb 01 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维护文件系统
2006/10/09 PHP
深入PHP变量存储的详解
2013/06/13 PHP
php发送get、post请求的6种方法简明总结
2014/07/08 PHP
ThinkPHP单字母函数(快捷方法)使用总结
2014/07/23 PHP
php通过文件头判断格式的方法
2016/05/28 PHP
php函数mkdir实现递归创建层级目录
2016/10/27 PHP
thinkphp5 加载静态资源路径与常量的方法
2017/12/24 PHP
php use和include区别总结
2019/10/13 PHP
js中复制行和删除行的操作实例
2013/06/25 Javascript
JavaScript字符串对象split方法入门实例(用于把字符串分割成数组)
2014/10/16 Javascript
JS实现点击文字对应DIV层不停闪动效果的方法
2015/03/02 Javascript
BootStrap Fileinput的使用教程
2016/12/30 Javascript
JavaScript实现前端分页控件
2017/04/19 Javascript
jQuery实现切换隐藏与显示同时切换图标功能
2017/10/29 jQuery
Webpack实战加载SVG的方法
2017/12/26 Javascript
Vue框架之goods组件开发详解
2018/01/25 Javascript
小程序从手动埋点到自动埋点的实现方法
2019/01/24 Javascript
JS apply用法总结和使用场景实例分析
2020/03/14 Javascript
Vue使用Ref跨层级获取组件的步骤
2021/01/25 Vue.js
[06:15]2016国际邀请赛中国区预选赛单车采访:我顶WINGS
2016/06/27 DOTA
[01:59]翻天覆地,因你而变,7.20版本地图更新速览
2018/11/24 DOTA
[01:33:30]DOTA2-DPC中国联赛 正赛 RNG vs Phoenix BO3 第二场 2月5日
2021/03/11 DOTA
探究数组排序提升Python程序的循环的运行效率的原因
2015/04/01 Python
python字典get()方法用法分析
2015/04/17 Python
如何处理Python3.4 使用pymssql 乱码问题
2016/01/08 Python
Python 实现选择排序的算法步骤
2018/04/22 Python
python 3.7.0 安装配置方法图文教程
2018/08/27 Python
Python函数any()和all()的用法及区别介绍
2018/09/14 Python
Python3 venv搭建轻量级虚拟环境的步骤(图文)
2019/08/09 Python
Python3自定义json逐层解析器代码
2020/05/11 Python
利用python实现汉诺塔游戏
2021/03/01 Python
Python面试题:Python里面如何生成随机数
2015/03/12 面试题
长城导游词
2015/01/30 职场文书
大学生村官工作总结2015
2015/04/09 职场文书
2016高考寄语或鼓励的话语
2015/12/04 职场文书
vue点击弹窗自动触发点击事件的解决办法(模拟场景)
2021/05/25 Vue.js