博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python全局解释器锁-----GIL
阅读量:6826 次
发布时间:2019-06-26

本文共 1339 字,大约阅读时间需要 4 分钟。

1.什么是全局解释器锁GIL

Python代码的执行由Python 虚拟机(也叫解释器主循环,CPython版本)来控制,Python 在设计之初就考虑到要在解释器的主循环中,同时只有一个线程在执行,即在任意时刻,只有一个线程在解释器中运行。对Python 虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁能保证同一时刻只有一个线程在运行。
 
2.在多线程环境中,Python 虚拟机按以下方式执行:
(1) 设置GIL
(2)切换到一个线程去运行
(3) 运行:
    a. 指定数量的字节码指令,或者
    b. 线程主动让出控制(可以调用time.sleep(0))
(4)把线程设置为睡眠状态
(5)解锁GIL
(6)再次重复以上所有步骤
 
3.GIL与lock
GIL保护的是解释器级的数据,保护用户自己的数据则需要自己加锁处理
 

首先我们需要达成共识:锁的目的是为了保护共享的数据,同一时间只能有一个线程来修改共享的数据

    然后,我们可以得出结论:保护不同的数据就应该加不同的锁。

 最后,问题就很明朗了,GIL 与Lock是两把锁,保护的数据不一样,前者是解释器级别的(当然保护的就是解释器级别的数据,比如垃圾回收的数据),后者是保护用户自己开发的应用程序的数据,很明显GIL不负责这件事,只能用户自定义加锁处理,即Lock

 
4.总结:
1.线程抢的是GIL锁,GIL锁相当于执行权限,拿到执行权限后才能拿到互斥锁Lock,其他线程也可以抢到GIL,但如果发现Lock仍然没有被释放则阻塞,即便是拿到执行权限GIL也要立刻交出来#2.join是等待所有,即整体串行,而锁只是锁住修改共享数据的部分,即部分串行,要想保证数据安全的根本原理在于让并发变成串行,join与互斥锁都可以实现,毫无疑问,互斥锁的部分串行效率要更高
 
5.GIL锁与互斥锁综合分析
#1.100个线程去抢GIL锁,即抢执行权限#2. 肯定有一个线程先抢到GIL(暂且称为线程1),然后开始执行,一旦执行就会拿到lock.acquire()#3. 极有可能线程1还未运行完毕,就有另外一个线程2抢到GIL,然后开始运行,但线程2发现互斥锁lock还未被线程1释放,于是阻塞,被迫交出执行权限,即释放GIL#4.直到线程1重新抢到GIL,开始从上次暂停的位置继续执行,直到正常释放互斥锁lock,然后其他的线程再重复2 3 4的过程

6.互斥锁与join的区别

#有的人可能有疑问:既然加锁会让运行变成串行,那么我在start之后立即使用join,就不用加锁了啊,也是串行的效果啊#没错:在start之后立刻使用jion,肯定会将100个任务的执行变成串行,毫无疑问,最终n的结果也肯定是0,是安全的,但问题是#start后立即join:任务内的所有代码都是串行执行的,而加锁,只是加锁的部分即修改共享数据的部分是串行的#单从保证数据安全方面,二者都可以实现,但很明显是加锁的效率更高

 

7.多线程与多进程的应用场景
 
(1)多线程用于IO密集型,如socket,爬虫,web
(2)多进程用于计算密集型,如金融分析
 
 

转载于:https://www.cnblogs.com/yxwang/p/7507432.html

你可能感兴趣的文章
微服务化的数据库设计与读写分离
查看>>
SpringMVC-----使用Maven创建Web项目
查看>>
Ribbon重试机制与Hystrix熔断机制的配置问题1
查看>>
CGI与FastCGI
查看>>
字符串查找算法的改进-hash查找算法
查看>>
c#实现远程图片下载
查看>>
史丹·温斯坦称傲牛熊市的秘密_百度百科
查看>>
SendMessage函数完全使用手册 转
查看>>
3GPP与3GPP2扫盲
查看>>
Android fragments loader
查看>>
淘宝下单高并发解决方案
查看>>
马尔科夫链算法
查看>>
JS框架
查看>>
hdu 1394
查看>>
【Cocos2D-X 】初窥门径(10)解决中文乱码
查看>>
LetterView实现载入全国各地城市
查看>>
设计模式——工厂方法
查看>>
算法训练 关联矩阵
查看>>
Git-随笔
查看>>
CSS系列:在HTML中引入CSS的方法
查看>>