千锋教育-做有情怀、有良心、有品质的职业教育机构

400-811-9990
手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:沈阳千锋IT培训  >  技术干货  >  Python 有可能删除 GIL 吗?

Python 有可能删除 GIL 吗?

来源:千锋教育
发布人:xqq
时间: 2023-11-09 03:25:42

我们知道,在CPython中,有一个全局解释器锁,英文叫globalinterpreterlock,简称GIL,是一个互斥锁,用来保护Python世界里的对象,防止同一时刻多个线程执行Python的字节码,从而确保线程安全,这导致了Python的线程无法利用多核CPU的优势,因此有人说Python的多线程是伪多线程,性能不高,那么Python将来有可能去除GIL吗?

要回答这个问题,先从GIL的起源进行分析。

GIL的起源

Python第一次发布是在1991年,当时的CPU都是单核,单核中,多线程主要为了一边做IO,一边做CPU计算而设计的,Python编译器是由C语言编写的,因此也叫CPython,那时候很多编程语言没有自动内存管理的功能,为了实现自动垃圾回收,Python为每一个对象进行了引用计数,当引用计数为0的时候说明该对象可以回收,从而释放内存了,比如:

>>>importsys>>>data={'gzh':'Python七号'}>>>var1=data>>>sys.getrefcount(data)3>>>

这里data对象就有3个引用,一个是本身,一个是变量var1,一个是getrefcount函数的参数,如果此时又有一个线程引用了data,那么引用计数再增加1,如果某个线程使用了data后运行结束,那么引用计数就减少1,多线程对同一个变量「引用计数」进行修改,就会遇到raceconditions(竞争),为了避免raceconditions,最简单有效的办法就是加一个互斥锁。

如果对每一个对象都加锁,有可能引发另一个问题,就是死锁,而且频繁的获取和释放会导致性能下降,最简单有效的方法就是加一个解释器锁,线程在执行任何字节码时都先获取解释器锁,这就避免了死锁,而且不会有太多的性能消耗。当时CPU都是单核,而且这种GIL设计简单,并不会影响性能,因此一直沿用至今天。GIL存在最主要的原因,就是因为Python的内存管理不是线程安全的,这就是GIL产生并存在的主要缘由。

尝试消除GIL

CPU进入多核时代后,可以同时做多个计算任务,GIL才真正变成问题。在1999年,有个叫GregStein的大佬基于Python1.5版本消除了GIL,取代代之的是在可变数据结构上加上更细粒度的锁,也提交了补丁用于去除对全局可变对象的依赖,然后在标准测试时表明去除GIL后单线程比不去除时慢了近2倍,测试的机器还是当时性能最好Windows机器。也就是说除去了GIL后,你使用2个CPU才能获取比原来1个CPU稍微好一点的性能,这种提升明显得不偿失,GregStein的尝试也就失败告终。

Python之父GuidovanRossum也欢迎社区的志愿者去尝试去除GIL,只要不降低单线程的性能,但他也提到,去掉GIL不是一件容易的事。

Python开发者邮件列表中也偶尔会有去除GIL的议题,但是以下需求必须满足:

简单。从长远来看该方案必须是可实施、可维护的。

并发。去除GIL必须能提升多线程的性能。

速度。去除GIL不能降低单线程的性能。

满足CPython的特性。该方案必须支持CPython的功能,比如__del__和弱引用。

API的兼容性。该方案应与所有现有CPython扩展使用的宏在源方面兼容。

及时销毁不可达对象,回收内存。

有序销毁,比如不可达对象X引用了A,那么应该在销毁A之前先销毁X(有些垃圾回收算法并不能做到这一点)。

有些需求不容易被满足,比如4,5,7,目前,还没有人满足以上需求的同时去除GIL成功的。

积重难返

这些年Python实在太火了,很多优秀的库都是基于CPython进行编写的,很多都是90年代的C扩展库,如果要除去GIL,那么很多基于GIL编写的C扩展便无法使用,也就是去了GIL,Python生态有很多扩展或三方库者无法使用。

还有一个很明显的例子,Python解释器不止有CPython,还有用Java编写的Python,.NET实现的IronPython,这些解释器完全没有GIL,可是有多少人为它们编写扩展呢?

Python之所以如此火爆,与它有着丰富的三方库开箱即用有着很大的关系,积重难返,去除GIL很困难。

为什么Python3一开始时不去除GIL

Python3在最开始时是有机会实现很多新功能,在此过程中,打破了一些现有的C扩展,然后需要更新和移植更改以配合Python3,这也是Python3一开始不被社区所接受的原因。

与Python2相比,删除GIL将使Python3在单线程性能方面更慢,而且很多优秀的扩展将不能再使用,如果真的这样,可以想象Python3不可能有未来,最终的结果是Python3仍然保持有GIL。

但Python3也为现有的GIL带来了重大改进,在Python3.2版本中,确保了计算密集型线程和I/O密集型线程并存时,I/O密集型长期获取不到GIL而无法执行的问题,提升了多线程的性能。

最后的话

Python因为内存管理不是线程安全的,因此自出生起就自带GIL,然后很多扩展都是在GIL的保护下编写的,时间一长积重难反,Python3一开始也因去除GIL导致单线程性能下降的问题而保留GIL,现在已经是Python3.9版本了,将来Python去除GIL的可能性微乎其微,换句话说,去除GIL的Python也就不是我们认识的Python了。

不过不必沮丧,GIL影响的也仅仅是多线程执行计算密集型的任务罢了,这种场景大多数程序员都很少遇到,即使有,可以使用多进程来避免GIL的影响,或者使用其他编程语言实现,任何编程语言或技术都不是十全十美的,发挥所长是最重要的,即使有GIL,我也不在乎,也会依然使用Python。

以上内容为大家介绍了Python有可能删除GIL吗?希望对大家有所帮助,如果想要了解更多Python相关知识,请关注IT培训机构:千锋教育。http://www.mobiletrain.org/

声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

猜你喜欢LIKE

pythontime模块的时间格式

2023-11-14

python怎样使用read读取不同类型文件

2023-11-14

python装饰属性的方法

2023-11-14

最新文章NEW

pythonsys模块有哪些用法

2023-11-14

python开发环境是什么

2023-11-14

pythoninsert函数是什么

2023-11-14

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>