什么是 GIL

栏目: Python · 发布时间: 4年前

内容简介:首先为什么要有Python使用引用计数来管理内存,也就是说Python中创建的对象有一个引用计数变量,该变量跟踪指向该对象的引用数量,当该计数到0时,对象占用的内存被释放。**显然,该引用计数不能同时被两个线程同时增加或减少值。**否则将可能导致内存泄漏(永远不会被释放)或不正确地释放(引用仍然存在)。

  首先 GIL(全局解释锁) 不是 Python 的特性,而是解释器CPtyhton的特性。 GIL 简言之是一个互斥锁,只允许一个线程控制 Python 解释器,也就是说,但任一时间点都只有一个线程处于执行状态。

为什么要设计GIL?

  为什么要有 GIL 呢,或者说 GIL 是为了解决什么问题呢?

  Python使用引用计数来管理内存,也就是说Python中创建的对象有一个引用计数变量,该变量跟踪指向该对象的引用数量,当该计数到0时,对象占用的内存被释放。**显然,该引用计数不能同时被两个线程同时增加或减少值。**否则将可能导致内存泄漏(永远不会被释放)或不正确地释放(引用仍然存在)。

  通过给线程间共享的所有数据结构加锁可以保证引用计数变量的安全性。但是这又导致一些问题:如果为每个对象添加锁就会导致多个锁的存在,有可能会导致死锁;再就是重复地获取和释放所有会降低性能。

  于是出现了 GILGIL 是解释器本身的锁,所有的 Python 获取 GIL 才能执行,这可以防止死锁并且不会带来太多心能开小。但它使得程序编程单线程。

  要注明的是, GIL 不是解决该问题的唯一方法。

为什么选择 GIL呢?

  首先,Python诞生的时候操作系统没有线程的概念;Python 的许多扩展使用 C 写的,而 C 扩展需要 GIL 提供的线程安全内存管理; GIL 易于实现,易于添加到 Python 中。

GIL 的影响 CPU 密集型和 IO 密集型

GIL锁的释放

  1. 协同式多任务处理:IO操作,在较长的或者不确定的时间,没有运行Python代码的需要,线程便会让出GIL;
  2. 抢占式多任务处理:对于CPU密集型的的程序,解释器运行一段时间就会放弃GIL,而不需要经过正在执行代码的线程允许,这样其他线程便能运行。(在python3中,这个时间间隔是15毫秒)

  任务可以分为 CPU密集型IO密集型CPU密集型 的特点是要进行大量的计算,消耗CPU资源,而 IO密集型 涉及网络、磁盘等IO操作,CPU消耗较小,任务的大部分时间都在等待IO操作完成。

   GIL 对两种任务的影响是不同的,对于完全CPU密集型任务, GIL 不仅会把多线程变成多线程,还会导致用时比单线程更长,因为涉及了锁的获取及释放;而IO密集型任务的性能则不会有太大影响。

为什么没有移除 GIL

  有人做过实验,移除 GIL 使用更小粒度的锁,发现单线程性能上降低非常严重,多线程程序也只有线程数达到一定数量时才有性能上的改进。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

互联网的误读

互联网的误读

詹姆斯•柯兰(James Curran)、娜塔莉•芬顿(Natalie Fenton)、德 斯•弗里德曼(Des Freedman) / 何道宽 / 中国人民大学出版社 / 2014-7-1 / 45.00

互联网的发展蔚为壮观。如今,全球的互联网用户达到20亿之众,约占世界人口的30%。这无疑是一个新的现象,对于当代各国的经济、政治和社会生活意义重大。有关互联网的大量大众读物和学术著作鼓吹其潜力将从根本上被重新认识,这在20世纪90年代中期一片唱好时表现尤甚,那时许多论者都对互联网敬畏三分,惊叹有加。虽然敬畏和惊叹可能已成过去,然而它背后的技术中心主义——相信技术决定结果——却阴魂不散,与之伴生的则......一起来看看 《互联网的误读》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具