python的GIL锁的是什么

有几个结论:
1、python的线程是原生线程,由操作系统调度
2、python的多线程环境下,每执行完100条指令后(称为“软时钟”)会触发一次“python级线程调度”,所谓的“python级线程调度”,指的是线程A释放GIL,线程B获得GIL,从而掌握了对解释器的“执行大权”。GIL实际上是再普通不过的线程锁,获得、释放GIL就是加解锁操作,像win32下是WaitForSingleObject和SetEvent,而solaris下则是mutex_lock和mutex_unlock。所以,“python级线程调度”本质上是GIL的锁争用,从某种意义上也可以说GIL锁被顺带用作“python级线程调度”。
3、GIL保护的是解释器,由于Python C-API是解释器的一部分,它也能保护Python C-API,但不能保护用户数据。所谓的“保护解释器”,是指GIL可避免解释器在多线程下破坏python对象的簿记信息,如引用计数。举个例子,线程A和B共享一个python对象,该对象不管是系统级对象还是用户级对象,其引用计数的修改和内存的回收都是由解释器自动完成的,写成伪码如下:
```
--obj->ref_cnt  [1]
if(obj->ref_cnt) free(obj) [2]
```
有多线程编程经验的人一眼就能看出,只有[1]和[2]组成一个原子操作,才可保证多线程下引用计数操作的正确性。按锁粒度最小化的原则,我们只需用一把锁保护住[1]和[2]即可,这把锁是细粒度锁。但python不这么做,它直接使用GIL这样的粗粒度锁,造成多线程串行执行上述伪码,自然也能保证安全。
由于GIL是一个粗粒度锁,在多核多线程下的效率自然不如细粒度锁,但作为脚本语言,单线程也是python的重要场景,而且单线程下像GIL这样的粗粒度锁是比较容易控制和优化掉的(事实上,单线程下GIL压根就不创建),反而像细粒度锁不太好优化。所以,历史上有人曾做过去除GIL的版本,其在单线程的基准测试中的表现反而不如GIL版本。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值