GIL

即全局解释器锁,是一个互斥锁,防止多个线程在同一时间执行python代码,因为在一个python进程中,不仅有主线程而且还有该主线程开启的子线程,还有解释器开启的垃圾回收机等解释器级别的线程。因为所有的代码都是共享的,所以垃圾回收线程也可能同时访问到解释器的代码去执行,所以解决这一问题的方法就是GIL,以保证python解释器同一时间只能执行同一个任务的代码。

GIL带来的问题

执行一个py文件,分为三个步骤:

  1. 从硬盘加载python解释器到内存
  2. 从硬盘加载py文件到内存
  3. 解释器解析py文件内容,交给CPU执行

需要明确的是每当执行一个py文件,就会立即启动一个python解释器

GIL是CPython解释器独有的,它将线程的并行变为串行,导致效率降低。

GIL对于性能的影响

  1. 单核下无论IO密集型还是计算密集型GIL都不会产生任何影响
  2. 多核下对于IO密集型任务,GIL会有细微影响,基本可以忽略
  3. CPython中IO密集型任务应该采用多线程,计算密集型应该采用多进程

另外:之所以广泛采用CPython解释器,就是因为大量的应用程序都是IO密集型的,还有另一个很重要的原因是CPython可以无缝对接各种C语言实现的库,这对于一些数学计算相关的应用程序而言非常的happy,直接就能使用各种现成的算法

自定义的线程锁和GIL的区别

GIL保护的是解释器级别的数据安全,比如对象的引用计数,垃圾回收机制等

对于程序中自己定义的数据则没有任何保护效果

from threading import Thread,Lock
import time a = 0
def task():
global a
temp = a
time.sleep(0.01)
a = temp + 1 t1 = Thread(target=task)
t2 = Thread(target=task)
t1.start()
t2.start()
t1.join()
t2.join()
print(a)
#1

过程分析:

1.线程1获得CPU执行权,并获取GIL锁执行代码 ,得到a的值为0后进入睡眠,释放CPU并释放GIL

2.线程2获得CPU执行权,并获取GIL锁执行代码 ,得到a的值为0后进入睡眠,释放CPU并释放GIL

3.线程1睡醒后获得CPU执行权,并获取GIL执行代码 ,将temp的值0+1后赋给a,执行完毕释放CPU并释放GIL

4.线程2睡醒后获得CPU执行权,并获取GIL执行代码 ,将temp的值0+1后赋给a,执行完毕释放CPU并释放GIL,最后a的值也就是1

之所以出现问题是因为两个线程在并发的执行同一段代码,解决方案就是加锁!

from threading import Thread,Lock
import time lock = Lock()
a = 0
def task():
global a
lock.acquire()
temp = a
time.sleep(0.01)
a = temp + 1
lock.release() t1 = Thread(target=task)
t2 = Thread(target=task)
t1.start()
t2.start()
t1.join()
t2.join()
print(a)
#2

过程分析:

1.线程1获得CPU执行权,并获取GIL锁执行代码 ,得到a的值为0后进入睡眠,释放CPU并释放GIL,不释放lock

2.线程2获得CPU执行权,并获取GIL锁,尝试获取lock失败,无法执行,释放CPU并释放GIL

3.线程1睡醒后获得CPU执行权,并获取GIL继续执行代码 ,将temp的值0+1后赋给a,执行完毕释放CPU释放GIL,释放lock,此时a的值为1

4.线程2获得CPU执行权,获取GIL锁,尝试获取lock成功,执行代码,得到a的值为1后进入睡眠,释放CPU并释放GIL,不释放lock

5.线程2睡醒后获得CPU执行权,获取GIL继续执行代码 ,将temp的值1+1后赋给a,执行完毕释放CPU释放GIL,释放lock,此时a的值为2

多线程--GIL锁的更多相关文章

  1. 并发编程-多线程,GIL锁

    本章内容: 1.什么是GIL 2.GIL带来的问题 3.为什么需要GIL 4.关于GIL的性能讨论 5.自定义的线程互斥锁与GIL的区别 6.线程池与进程池 7.同步异步,阻塞非阻塞 一.什么是GIL ...

  2. python爬虫之多线程、多进程、GIL锁

    背景: 我们知道多线程要比多进程效率更高,因为线程存在于进程之内,打开一个进程的话,首先需要开辟内存空间,占用内存空间比线程大.这样想也不怪,比如一个进程用10MB,开10个进程就得100MB的内存空 ...

  3. [Python 多线程] GIL全局解释器锁 (十三)

    Queue 标准库queue模块,提供FIFO(先进先出)的Queue.LIFO(后进先出)的队列.优先队列. Queue类是线程安全的,适用于多线程间安全的交换数据.内部使用了Lock和Condit ...

  4. 网络编程之多线程——GIL全局解释器锁

    网络编程之多线程--GIL全局解释器锁 一.引子 定义: In CPython, the global interpreter lock, or GIL, is a mutex that preven ...

  5. python笔记9 线程进程 threading多线程模块 GIL锁 multiprocessing多进程模块 同步锁Lock 队列queue IO模型

    线程与进程 进程 进程就是一个程序在一个数据集上的一次动态执行过程.进程一般由程序.数据集.进程控制块三部分组成.我们编写的程序用来描述进程要完成哪些功能以及如何完成:数据集则是程序在执行过程中所需要 ...

  6. [并发编程 - 多线程:信号量、死锁与递归锁、时间Event、定时器Timer、线程队列、GIL锁]

    [并发编程 - 多线程:信号量.死锁与递归锁.时间Event.定时器Timer.线程队列.GIL锁] 信号量 信号量Semaphore:管理一个内置的计数器 每当调用acquire()时内置计数器-1 ...

  7. Python的多线程GIL浅谈

    来源知乎:https://www.zhihu.com/question/23474039/answer/269526476 在介绍Python中的线程之前,先明确一个问题,Python中的多线程是假的 ...

  8. 53_并发编程-线程-GIL锁

    一.GIL - 全局解释器锁   有了GIL的存在,同一时刻同一进程中只有一个线程被执行:由于线程不能使用cpu多核,可以开多个进程实现线程的并发,因为每个进程都会含有一个线程,每个进程都有自己的GI ...

  9. python 线程(创建2种方式,锁,死锁,递归锁,GIL锁,守护进程)

    ###############总结############ 线程创建的2种方式(重点) 进程:资源分配单位    线程:cpu执行单位(实体) 线程的创建和销毁的开销特别小 线程之间资源共享,是同一个 ...

随机推荐

  1. 错误 175: 具有固定名称“MySql.Data.MySqlClient”的 ADO.NET 提供程序未在计算

    问题描述:错误 175: 具有固定名称“MySql.Data.MySqlClient”的 ADO.NET 提供程序未在计算 原因描述:一.首先我的系统是因为是win10 的有问题,重新装了系统. 二. ...

  2. vue tabNav 点击

    <template> <div class="content"> <header class="tab_nav"> < ...

  3. ZF、TP、CI等各种框架的区别

    (原标题:面试常见问题之ZF.TP.CI等框架的区别 http://blog.163.com/m13341159039_1/blog/static/245953061201522092212820/) ...

  4. bzoj1057: [ZJOI2007]棋盘制作 [dp][单调栈]

    Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应 ...

  5. 【Codeforces 1148B】Born This Way

    [链接] 我是链接,点我呀:) [题意] 有人要从A地飞向B地,然后从B地飞向C地. 给出A,B地的n.m个航班的出发时间. 已知从A到B的航班都是ta和tb时长到达B.C 只有到达B的时候航班还没起 ...

  6. bzoj1016题解

    [解题思路] Kruskal的拓展. 可以先对边排序,进行一次Kruskal,判断是否可行,并计算出每种权值的边需要多少条. 然后暴力统计每种权值可行的方案数,根据乘法原理乘起来即可.复杂度o(210 ...

  7. NX二次开发-UFUN输入对象tag获得part名字UF_OBJ_ask_owning_part

    NX11+VS2013 #include <uf.h> #include <uf_modl.h> #include <uf_part.h> #include < ...

  8. Java-Class-C:org.springframework.http.HttpEntity

    ylbtech-Java-Class-C:org.springframework.http.HttpEntity 1.返回顶部 1.1. import org.springframework.http ...

  9. LeetCode 744. Find Smallest Letter Greater Than Target (寻找比目标字母大的最小字母)

    题目标签:Binary Search 题目给了我们一组字母,让我们找出比 target 大的最小的那个字母. 利用 binary search,如果mid 比 target 小,或者等于,那么移到右半 ...

  10. Aliyun 安装NPM 总是3.5.2 解决方案

    由于默认的命令 阿里云安装的 Node 是 8.x 版本 导致NPM 一直安装的都是 3.5.2 版本,死活升级不上去 最后手动安装指定版本解决 wget -qO- https://deb.nodes ...