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 相关文章推荐
将pandas.dataframe的数据写入到文件中的方法
Dec 07 Python
Python微信操控itchat的方法
May 31 Python
python3.4 将16进制转成字符串的实例
Jun 12 Python
Python提取PDF内容的方法(文本、图像、线条等)
Sep 25 Python
python生成器推导式用法简单示例
Oct 08 Python
如何基于Python + requests实现发送HTTP请求
Jan 13 Python
Python原始套接字编程实例解析
Jan 29 Python
python中使用input()函数获取用户输入值方式
May 03 Python
浅谈TensorFlow之稀疏张量表示
Jun 30 Python
python如何实现图片压缩
Sep 11 Python
如何用python 操作zookeeper
Dec 28 Python
手把手教你怎么用Python实现zip文件密码的破解
May 27 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
先进的自动咖啡技术,真的可以取代咖啡师吗?
2021/03/06 冲泡冲煮
php trim 去除空字符的定义与语法介绍
2010/05/31 PHP
WebQQ最新登陆协议的用法
2014/12/22 PHP
php输入数据统一类实例
2015/02/23 PHP
php生成静态html页面的方法(2种方法)
2015/09/14 PHP
thinkphp3.2实现在线留言提交验证码功能
2017/07/19 PHP
php根据命令行参数生成配置文件详解
2019/03/15 PHP
thinkphp框架使用JWTtoken的方法详解
2019/10/10 PHP
jquery全选/全不选/反选另一种实现方法(配合原生js)
2013/04/07 Javascript
javascript禁用Tab键脚本实例
2013/11/22 Javascript
javascript实现des解密加密全过程
2014/04/03 Javascript
js获取日期:昨天今天和明天、后天
2014/06/11 Javascript
由浅入深讲解Javascript继承机制与simple-inheritance源码分析
2015/12/13 Javascript
纯javascript版日历控件
2016/11/24 Javascript
纯js实现动态时间显示
2020/09/07 Javascript
backbone简介_动力节点Java学院整理
2017/07/14 Javascript
简单实现jQuery手风琴效果
2017/08/18 jQuery
Vue cli构建及项目打包以及出现的问题解决
2018/08/27 Javascript
原生js实现公告滚动效果
2021/01/10 Javascript
使用python搭建Django应用程序步骤及版本冲突问题解决
2013/11/19 Python
Python itertools模块详解
2015/05/09 Python
在Python中使用next()方法操作文件的教程
2015/05/24 Python
python删除过期文件的方法
2015/05/29 Python
利用 python 对目录下的文件进行过滤删除
2017/12/27 Python
Python使用正则表达式获取网页中所需要的信息
2018/01/29 Python
Django如何开发简单的查询接口详解
2019/05/17 Python
用Python抢火车票的简单小程序实现解析
2019/08/14 Python
远程教育心得体会
2014/01/03 职场文书
三方合作协议书范本
2014/04/18 职场文书
党员个人查摆剖析材料
2014/10/16 职场文书
2015共产党员公开承诺书
2015/01/22 职场文书
公司副总经理岗位职责
2015/04/08 职场文书
2015年工商所工作总结
2015/05/21 职场文书
2016关于预防职务犯罪的心得体会
2016/01/21 职场文书
会计手工模拟做账心得体会
2016/01/22 职场文书
详解jQuery的核心函数和事件处理
2022/02/18 jQuery