找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 5958|回复: 0

Python 3.2与更好的GIL

[复制链接]
发表于 2012-11-10 19:21:04 | 显示全部楼层 |阅读模式
Python 3.2于已经正式发布。在Python 3.1发布之后,根据Guido的建议 (PEP 3003),Python的开发人员在2011年6月份之前,都不再对Python语言进行大的修改,而是将主要精力集中在修复bug,提高稳定性以及性能上。现在Python 3.2带着这样的目标到来了。
Python 3.2带来的改进有很多,其中一个惹人注目的改动是重新实现的GIL (Global Interpreter Lock)。众所周知,Python(这里说的Python实际上是Python语言的参考实现CPython)的GIL是阻碍Python性能提升的一个屏障,因为有GIL的存在,即使Python提供了非常优雅简洁的threading库接口,你实际上还是无法享用多线程所带来的性能提升,因为本质上GIL只允许一个线程在Python进程下运行。也因此从GIL诞生的那天起,关于去掉GIL的争论就一直没停止过。对此,Guido以及Python的开发人员都有一个很明确的解释,那就是去掉GIL并不容易,或者说是不值当的。


如果说在Python下使用多线程,因为GIL的存在而不起效用的话也就罢了。更令人不能接受的是,在某些情况下,使用多线程不光不能提高效率,反而会降低效率,尤其是在多CPU的机器上,效率反而比单CPU(将其余CPU禁止)要低很多。这样的结果无论如何是说不过去的。David Beazley曾经对此做过非常详细的分析,以及解释。原因大体如下:
Python使用GIL来控制任何时候只能有一个线程运行,并且Python来控制线程何时释放GIL,而底层的OS来控制哪个线程获取GIL。Python在遇到两种情况下强制某个线程释放GIL,一是该线程要进行IO操作,二是该线程已经执行了某个数量的opcode。这样的机制就带来了

两个问题:

  • 使用固定数量的opcode做为单位来强制切换线程,必然是粗糙的,不准确的,因为有的代码可能执行的很快,而有的则更耗时。
  • 让OS来选择哪个线程执行,有时候是无法预测的(尤其在多CPU下)。比如有可能造成某个线程刚刚释放GIL,却马上又获取了GIL。

针对这些问题,Antoine Pitrou对GIL的实现进行了重写,他曾在Python的开发列表上详细阐述了重新实现的机制:

  • 使用固定的时间而不是固定数量的opcode来进行线程的强制切换。这样就解决了上述问题1,但使用固定的时间仍然是相当机械的,有可能在这个时间内,某个优先级更高的线程(比如一个IO等待操作正巧数据来了)需要运行,却只能等待。
  • 在线程释放GIL后,开始等待,直到某个其它线程获取GIL后,再开始去尝试获取GIL。这样可以避免此前获得GIL的线程,不会立即再次获取GIL,但仍然无法保证优先级高的线程获取GIL。

Pitrou对GIL的重新实现也就是现在3.2版本的GIL,解决了相当一部分问题。但仍然有部分极端情况未能解决,归根结底在于在GIL的释放由Python来控制,但GIL由哪个线程获取却仍然是底层的OS来决定的,而这仍然有可能带来性能的下降。
为此Beazley专门向Python发了一个bug,附上了相关的测试脚本,并介绍了一种可能的解决办法。在这个bug的解决上,相关开发人员对此进行了详细的分析与测试,如果要解决这个问题,显然必须要把部分kernel的调度机制,挪到Python里,也就是必须对Python的线程区分优先级。Nir Aides为此专门将Kernel的Brainfuck调度算法,在Python里重新实现并做了相应的patch。但该patch并没有集成到3.2中,对此的解释是针对线程调度的修改最好慢慢来,这个问题需要实际的应用来证实确实需要修复。目前看来,也许在3.3中才能看到该修复。

当然即使该问题得到了修复,Python的多线程也看起来更加完善,但从根本上,仍然还在GIL上转圈圈。仍然会有刚了解Python的开发人员去质疑为什么不去掉GIL,尤其是在今天,多CPU已经成为标准的配置。但至少在很长的时间内,你听到的答复都将是,很困难,去不掉,你只能选择使用多进程,或者用C扩展的方式来绕过GIL。

这样的答复即使理由足够充分,也无法令人满意。毕竟在解决问题时,谁都希望能有更多选择。但事实上,Python在经过这么多年的发展后,对于GIL的依赖已经积重难返,悲观的说,GIL已不太可能从Python中去掉。除非某个有勇气的人,将Python重新实现。

您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-4-26 00:59 , Processed in 0.012927 second(s), 7 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表