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中将单词首字母大写的capitalize()方法
May 18 Python
Python写入数据到MP3文件中的方法
Jul 10 Python
你应该知道的python列表去重方法
Jan 17 Python
Python实现随机生成有效手机号码及身份证功能示例
Jun 05 Python
Python基础教程之浅拷贝和深拷贝实例详解
Jul 15 Python
Python微信企业号开发之回调模式接收微信端客户端发送消息及被动返回消息示例
Aug 21 Python
python twilio模块实现发送手机短信功能
Aug 02 Python
djano一对一、多对多、分页实例代码
Aug 16 Python
Python爬取腾讯视频评论的思路详解
Dec 19 Python
pytorch中nn.Conv1d的用法详解
Dec 31 Python
利用python为PostgreSQL的表自动添加分区
Jan 18 Python
Python爬虫之自动爬取某车之家各车销售数据
Jun 02 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实现双链表删除与插入节点的方法示例
2017/11/11 PHP
PHP命名空间用法实例分析
2019/09/04 PHP
JAVASCRIPT HashTable
2007/01/22 Javascript
jquery.cookie.js 操作cookie实现记住密码功能的实现代码
2011/04/27 Javascript
全面理解面向对象的 JavaScript(来自ibm)
2013/11/10 Javascript
js+css 实现遮罩居中弹出层(随浏览器窗口滚动条滚动)
2013/12/11 Javascript
JavaScript中获取高度和宽度函数总结
2014/10/08 Javascript
js脚本实现数据去重
2014/11/27 Javascript
Angularjs 基础入门
2014/12/26 Javascript
Bootstrap打造一个左侧折叠菜单的系统模板(二)
2016/05/17 Javascript
简单实现jQuery进度条轮播实例代码
2016/06/20 Javascript
js鼠标按键事件和键盘按键事件用法实例汇总
2016/10/03 Javascript
Bootstrap源码解读按钮(5)
2016/12/23 Javascript
浅谈在fetch方法中添加header后遇到的预检请求问题
2017/08/31 Javascript
深入理解Vue生命周期、手动挂载及挂载子组件
2017/09/27 Javascript
vue通过滚动行为实现从列表到详情,返回列表原位置的方法
2018/08/31 Javascript
Bootbox将后台JSON数据填充Form表单的实例代码
2018/09/10 Javascript
vue2 v-model/v-text 中使用过滤器的方法示例
2019/05/09 Javascript
nodejs中使用archive压缩文件的实现代码
2019/11/26 NodeJs
JavaScript如何实现监听键盘输入和鼠标监点击
2020/07/20 Javascript
Python开发常用的一些开源Package分享
2015/02/14 Python
Python中的上下文管理器和with语句的使用
2018/04/17 Python
详解python异步编程之asyncio(百万并发)
2018/07/07 Python
详解pandas安装若干异常及解决方案总结
2019/01/10 Python
django框架用户权限中的session缓存到redis中的方法
2019/08/06 Python
PyQt+socket实现远程操作服务器的方法示例
2019/08/22 Python
Python 动态导入对象,importlib.import_module()的使用方法
2019/08/28 Python
PyTorch中 tensor.detach() 和 tensor.data 的区别详解
2020/01/06 Python
Python Django form 组件动态从数据库取choices数据实例
2020/05/19 Python
python识别验证码的思路及解决方案
2020/09/13 Python
python实现网页录音效果
2020/10/26 Python
英语自荐信常用语句
2013/12/13 职场文书
应届大专生自荐书
2014/06/16 职场文书
招标授权委托书样本
2014/09/23 职场文书
2015年党风廉政承诺书
2015/01/22 职场文书
Python turtle实现贪吃蛇游戏
2021/06/18 Python