GIL锁
GIL锁 在CPython中,这个全局解释器锁,也称GIL,是一个互斥锁,防止多个线程在同一时间执行pyonty字节码,这个锁是非常重要的,因为cpython的内存管理非线程安全的,很多其他的特性依赖于GIL,所以即使它影响了程序效率也无法将其直接去掉。 总结:在cpython中,GIL会把线程的并行变成串行,导致效率降低(需要的是知道的是,解释器并不是只有cpython,还有pypy,jpython等等。GIL也存在与cpython中,这并不是python这门语言的问题,而是cpython解释器的问题)
GIL与GC的孽缘
在使用Python中进行编程时,程序员无需参与内存的管理工作,这是因为Python有自带的内存管理机制,简称GC。那么GC与GIL有什么关联?
要搞清楚这个问题,需先了解GC的工作原理,Python中内存管理使用的是引用计数,每个数会被加上一个整型的计数器,表示这个数据被引用的次数,当这个整数变为0时则表示该数据已经没有人使用,成了垃圾数据。
当内存占用达到某个阈值时,GC会将其他线程挂起,然后执行垃圾清理操作,垃圾清理也是一串代码,也就需要一条线程来执行。
示例代码:
from threading import Thread
def task():
a = 10
print(a)
# 开启三个子线程执行task函数
Thread(target=task).start()
Thread(target=task).start()
Thread(target=task).start()
通过上图可以看出,GC与其他线程都在竞争解释器的执行权,而CPU何时切换,以及切换到哪个线程都是无法预支的,这样一来就造成了竞争问题,假设线程1正在定义变量a=10,而定义变量第一步会先到到内存中申请空间把10存进去,第二步将10的内存地址与变量名a进行绑定,如果在执行完第一步后,CPU切换到了GC线程,GC线程发现10的地址引用计数为0则将其当成垃圾进行了清理,等CPU再次切换到线程1时,刚刚保存的数据10已经被清理掉了,导致无法正常定义变量。
当然其他一些涉及到内存的操作同样可能产生问题问题,为了避免GC与其他线程竞争解释器带来的问题,CPython简单粗暴的给解释器加了互斥锁,如下图所示:有了GIL后,多个线程将不可能在同一时间使用解释器,从而保证了解释器的数据安全。
GIL的加锁与解锁时机
加锁的时机:在调用解释器时立即加锁
解锁时机:
当前线程遇到了IO时释放
当前线程执行时间超过设定值时释放
GIL的优点:
保证了CPython中的内存管理是线程安全的
GIL的缺点:
互斥锁的特性使得多线程无法并行
但我们并不能因此就否认Python这门语言,其原因如下:
GIL仅仅在CPython解释器中存在,在其他的解释器中没有,并不是Python这门语言的缺点
在单核处理器下,多线程之间本来就无法真正的并行执行
在多核处理下,运算效率的确是比单核处理器高,但是要知道现代应用程序多数都是基于网络的(qq,微信,爬虫,浏览器等等),CPU的运行效率是无法决定网络速度的,而网络的速度是远远比不上处理器的运算速度,则意味着每次处理器在执行运算前都需要等待网络IO,这样一来多核优势也就没有那么明显了
总结:
1.单核下无论是IO密集还是计算密集GIL都不会产生任何影响
2.多核下对于IO密集任务,GIL会有细微的影响,基本可以忽略
3.Cpython中IO密集任务应该采用多线程,计算密集型应该采用多进程
另外:之所以广泛采用CPython解释器,就是因为大量的应用程序都是IO密集型的,还有另一个很重要的原因是CPython可以无缝对接各种C语言实现的库,这对于一些数学计算相关的应用程序而言非常的happy,直接就能使用各种现成的算法
GIL锁的更多相关文章
- 53_并发编程-线程-GIL锁
一.GIL - 全局解释器锁 有了GIL的存在,同一时刻同一进程中只有一个线程被执行:由于线程不能使用cpu多核,可以开多个进程实现线程的并发,因为每个进程都会含有一个线程,每个进程都有自己的GI ...
- python爬虫之多线程、多进程、GIL锁
背景: 我们知道多线程要比多进程效率更高,因为线程存在于进程之内,打开一个进程的话,首先需要开辟内存空间,占用内存空间比线程大.这样想也不怪,比如一个进程用10MB,开10个进程就得100MB的内存空 ...
- python 线程(创建2种方式,锁,死锁,递归锁,GIL锁,守护进程)
###############总结############ 线程创建的2种方式(重点) 进程:资源分配单位 线程:cpu执行单位(实体) 线程的创建和销毁的开销特别小 线程之间资源共享,是同一个 ...
- 线程有gil锁
gil锁作用: 遇到阻塞( 比如 recv() , accept() )就切换
- GIL锁、进程池与线程池
1.什么是GIL? 官方解释: ''' In CPython, the global interpreter lock, or GIL, is a mutex that prevents multip ...
- Python GIL锁
GIL全局解释器锁:为了解决多线程修改同一块数据. python的线程是调用操作系统的源生线程,启动时就是调用C语言的C源生接口,python调用C语言接口的线程去执行任务时,必须上下文对应关系传给C ...
- day34 GIL锁 线程队列 线程池
一.Gil锁(Global Interpreter Lock) python全局解释器锁,有了这个锁的存在,python解释器在同一时间内只能让一个进程中的一个线程去执行,这样python的多线程就无 ...
- day36 GIL锁与线程池
多进程与多线程效率对比 # # """ # # 计算密集型 # """ # from threading import Thread # f ...
- GIL锁,线程池
内容梗概: 1.线程队列 2.线程池 3.GIL锁 1.线程队列 1.1先进先出队列(FIFO)import queueq = queue.Queue(3)q.put(1)q.put(2)q.put( ...
随机推荐
- 第27月第10天 cmake
1.error: tool 'xcodebuild' requires Xcode的解决办法 sudo xcode-select --switch /Applications/Xcode.app/Co ...
- java实现excel生成和导出
1.java生成excel 2.java读取excel内容
- 【CentOS】JDK的安装
FTP文件上传方式(推荐) # 解压 tar zxvf jdk-9_linux-x64_bin.tar.gz # 修改profile文件 sudo vi /etc/profile # 在文件结尾添加如 ...
- tidb调研
TiDB是新一代开源分布式 NewSQL 数据库,相比较于我们常见的数据库MySQL,TiDB具有水平伸缩.强一致性的分布式事务.基于 Raft 算法的多副本复制等特性.同时,TiDB兼容MySQL生 ...
- L - Tic-Tac-Toe FZU - 2283 (思维)
题目链接: L - Tic-Tac-Toe FZU - 2283 题目大意:两个人下棋,一共是三步棋,第一个人下一步,第二个人下一步,第三个人下一步,然后问你在两个人在都足够聪明的条件下,第一个人能否 ...
- zabbix系列 ~ 自动监控多实例功能
一 场景 监控mongo的多实例端口二 目标 定制一套模板,根据不同的端口进行批量监控项的生成三 步骤 1 编写py脚本实现端口josin化输出,以便zabbix_server能进行识别 ...
- Css - 页面标签页图标
Css - 页面标签页图标 <head> <meta charset="utf-8" /> <title>京东(JD.COM)- ...
- 【NLP CS224N笔记】Lecture 2 - Word Vector Representations: word2vec
I. Word meaning Meaning的定义有很多种,其中有: the idea that is represented by a word,phrase,etc. the idea that ...
- ListBox滚动条 刷新列表之后 指定位置(置顶或滚动到最后)
参数ObservableCollection<T>类型 滚动条在最上 ListBox.ScrollIntoView(ListBoxOC[0]);滚动条在最下 ListBox.ScrollI ...
- eMMC基础技术5:emmc response
1.前言 response是由device发给host,作为对先前发送的command的回应.response通过cmd信号线传输.本文将详细介绍response相关 2.response的类型 re ...