Cpython解释器中的GIL全局解释器锁
作者:Sg、 发布时间:2021-08-29 22:06:43
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()一样,另外其他的线程才开始跑起来。
来源:https://www.cnblogs.com/jsxxd/p/13944349.html
猜你喜欢
- 笔者通过一周的时间,询问了许多设计人员真实用户,以便确保这六个方面确实是大多数用户所不喜并且有非常大的概率普遍存在于众多的医疗网站之中。那么
- 记录应用程序的操作日志可以使用数据库、文本文件、XML文件等。我这里介绍的是使用 XML 文件记录操作日志。我觉得使用 XML 记录操作日志
- 很多时候,我们都需要获取windows消息提示框的文本内容,例如系统异常信息,软件错误提示等。。。但是如何获取提示信息呢?通常我们的印象中,
- 我们有时候看到一些文章因为一行的字符超长而把一些表格或DIV撑开或字符写到溢出了.如何防止表格防止撑开,表格不被内容撑开,单行字符超长div
- 本文介绍了10个asp网页制作的常用到的技巧,有asp的也有javascript。如asp如何获取系统时间,如何取得IP,及浏览
- 方法一:利用Cookies对象 因为Cookies对象把变量的值保存在浏览器客户端,所以可以根据Cookies保存的IsVoted的值来判断
- 在Linux系统下Python连接Redis的基本配置方法具体操作步骤系统环境:OS:Oracle Linux Enterprise 5.6
- 前言当我们需要对列表(list)、元组(tuple)、字典(dictionary)和集合(set)的元素进行遍历时,其实Python内部都是
- 注意,在改变数值之前锁定应用,确保一段时间里只有一个客户执行该语句。<SCRIPT LANGUAGE="VBScr
- 先前在DW教学-Dreamweaver量身打造Wordpress留言板(一) 教学文章中,已经成功的把前端留言机制与界面搞定了,虽然有了留言
- 网站设计时,有一个最常用的指导性原则:页面长度原则上不超过3屏,宽度不超过1屏。这个原则明显是从用户的体验出发,特别是宽度不超过一屏,其最基
- 知识点: Array方法: sort:降序 reverse:反序 效果: 代码: <style> *{ margin
- 阅读上一篇:FrontPage2002简明教程七:HTML在FrontPage中的应用 FrontPage 2002比起以前版本的FronP
- 在mysql安装目录的bin下, 运行mysql --install MYSQL5查看服务中, 会多一个MYSQL5的服务XAMPP的控制面
- 107条javascript(js)常用的方法技巧,十分的实用,相信看了下面的这些js编程技巧和方法,能够给javascript初学者解决很
- 如何显示最后十名来访者?代码和说明见下:<%Application.LockIF NOT isArray(&nbs
- 首先要把php_iconv.dll和inconv.dll COPY到c:\winnt\system32下,直接上代码:<?define
- 如何用组件实现自动发送电子邮件?我想做一个能够自动发送电子邮件的程序,该如何做? 这就要用到w3 upl
- 文章背景:某天,我的一个同事给我看了CSDN上面的一篇关于编程语言排行榜的文章,里面我看到VB还是排名很不错的,我就说,asp(vbscri
- MySQL安装文件已被广泛应用但是也在不断的更新,这里介绍MySQL安装文件设置使用,帮助大家安装更新MySQL安装文件系统。Fedora5