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 相关文章推荐
简单介绍Ruby中的CGI编程
Apr 10 Python
python超简单解决约瑟夫环问题
May 12 Python
python中(str,list,tuple)基础知识汇总
Feb 20 Python
详解关于Django中ORM数据库迁移的配置
Oct 08 Python
Python深拷贝与浅拷贝用法实例分析
May 05 Python
检测python爬虫时是否代理ip伪装成功的方法
Jul 12 Python
python3 mmh3安装及使用方法
Oct 09 Python
基于python的docx模块处理word和WPS的docx格式文件方式
Feb 13 Python
Django多层嵌套ManyToMany字段ORM操作详解
May 19 Python
详解Python IO编程
Jul 24 Python
python 视频下载神器(you-get)的具体使用
Jan 06 Python
教你怎么用Python生成九宫格照片
May 20 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实现的随机广告显示代码
2007/06/14 PHP
php设计模式 DAO(数据访问对象模式)
2011/06/26 PHP
php求正负数数组中连续元素最大值示例
2014/04/11 PHP
PHP中使用CURL模拟登录并获取数据实例
2014/07/01 PHP
php动态函数调用方法
2015/05/21 PHP
PHP 获取ip地址代码汇总
2015/07/05 PHP
实例讲解PHP设计模式编程中的简单工厂模式
2016/02/29 PHP
PHP基于简单递归函数求一个数阶乘的方法示例
2017/04/26 PHP
PHP程序员学习使用Swoole的理由
2018/06/24 PHP
JS JavaScript获取Url参数,src属性参数
2021/03/09 Javascript
javascript 多级checkbox选择效果
2009/08/20 Javascript
JavaScript建立一个语法高亮输入框实现思路
2013/02/26 Javascript
Jquery方式获取iframe页面中的 Dom元素
2014/05/07 Javascript
jQuery实现判断滚动条到底部
2015/06/23 Javascript
微信小程序 聊天室简单实现
2017/04/19 Javascript
javascript高级模块化require.js的具体使用方法
2017/10/31 Javascript
详解javascript中的Error对象
2019/04/25 Javascript
p5.js临摹旋转爱心
2019/10/23 Javascript
element-ui中dialog弹窗关闭按钮失效的解决
2020/09/22 Javascript
js实现验证码干扰(动态)
2021/02/23 Javascript
Python数据类型详解(一)字符串
2016/05/08 Python
Python编程实现正则删除命令功能
2017/08/30 Python
获取django框架orm query执行的sql语句实现方法分析
2019/06/20 Python
python画双y轴图像的示例代码
2019/07/07 Python
Python遍历字典方式就实例详解
2019/12/28 Python
使用Python实现将多表分批次从数据库导出到Excel
2020/05/15 Python
python os.rename实例用法详解
2020/12/06 Python
python批量提取图片信息并保存的实现
2021/02/05 Python
美国知名的在线旅游服务网站:Priceline
2016/07/23 全球购物
意大利宠物用品购物网站:Bauzaar
2018/09/15 全球购物
TheFork葡萄牙:欧洲领先的在线餐厅预订平台
2019/05/27 全球购物
JBL加拿大官方商店:扬声器、耳机等
2020/10/23 全球购物
小型女装店的创业计划书
2014/01/09 职场文书
电子装配专业毕业生求职信
2014/04/23 职场文书
nginx网站服务如何配置防盗链(推荐)
2021/03/31 Servers
关于JS中的作用域中的问题思考分享
2022/04/06 Javascript