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 Django做网页
Nov 04 Python
python去除扩展名的实例讲解
Apr 23 Python
Pycharm更换python解释器的方法
Oct 29 Python
python之Flask实现简单登录功能的示例代码
Dec 24 Python
为什么你还不懂得怎么使用Python协程
May 13 Python
PyQt QCombobox设置行高的方法
Jun 20 Python
PyTorch中Tensor的拼接与拆分的实现
Aug 18 Python
Python操作excel的方法总结(xlrd、xlwt、openpyxl)
Sep 02 Python
Python 窗体(tkinter)下拉列表框(Combobox)实例
Mar 04 Python
Python Selenium截图功能实现代码
Apr 26 Python
python ansible自动化运维工具执行流程
Jun 24 Python
Python实现批量将文件复制到新的目录中再修改名称
Apr 12 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运行时强制显示出错信息的代码
2011/04/20 PHP
解析mysql 表中的碎片产生原因以及清理
2013/06/22 PHP
PHP实现长文章分页实例代码(附源码)
2016/02/03 PHP
ThinkPHP框架使用redirect实现页面重定向的方法实例分析
2018/04/12 PHP
在IE6下发生Internet Explorer cannot open the Internet site错误
2010/06/21 Javascript
js原生态函数中使用jQuery中的 $(this)无效的解决方法
2011/05/25 Javascript
javascript学习笔记(十二) RegExp类型介绍
2012/06/20 Javascript
NodeJS实现阿里大鱼短信通知发送
2016/01/17 NodeJs
jQuery实用小技巧_输入框文字获取和失去焦点的简单实例
2016/08/25 Javascript
EasyUI的DataGrid绑定Json数据源的示例代码
2017/12/16 Javascript
Node.js中的cluster模块深入解读
2018/06/11 Javascript
详解使用VUE搭建后台管理系统(vue-cli更新至3.0)
2018/08/22 Javascript
vue.js 子组件无法获取父组件store值的解决方式
2019/11/08 Javascript
vue基于v-charts封装双向条形图的实现代码
2019/12/09 Javascript
Python 返回汉字的汉语拼音
2009/02/27 Python
Python算法应用实战之栈详解
2017/02/04 Python
Python yield 使用方法浅析
2017/05/20 Python
Python3使用turtle绘制超立方体图形示例
2018/06/19 Python
python通过zabbix api获取主机
2018/09/17 Python
面向初学者的Python编辑器Mu
2018/10/08 Python
python 发送和接收ActiveMQ消息的实例
2019/01/30 Python
用Pytorch训练CNN(数据集MNIST,使用GPU的方法)
2019/08/19 Python
PYQT5开启多个线程和窗口,多线程与多窗口的交互实例
2019/12/13 Python
Python绘制组合图的示例
2020/09/18 Python
Python实现FTP文件定时自动下载的步骤
2020/12/19 Python
python 将Excel转Word的示例
2021/03/02 Python
纯CSS3实现鼠标滑过按钮动画第二节
2020/07/16 HTML / CSS
曼联官方网上商店:Manchester United Direct
2017/07/28 全球购物
Hudson Jeans官网:高级精制牛仔裤
2018/11/28 全球购物
编程用JAVA解析XML的方式
2013/07/07 面试题
领导调研接待方案
2014/02/27 职场文书
后备干部培训方案
2014/05/22 职场文书
小学校园广播稿
2015/08/18 职场文书
刚学完怎么用Python实现定时任务,转头就跑去撩妹!
2021/06/05 Python
浅谈Node的内存泄露问题
2022/05/06 NodeJs
使用CSS自定义属性实现骨架屏效果
2022/06/21 HTML / CSS