去掉GIL不容易

昨天,Juergen Brendel在他的博客中 详细列出GIL的诸多不足。他声称这是我做的一个架构决策,而此决策限制了他的生产率。

我并不期待这个回复或其它任何回复能停止去除GIL的请求,尽管关于此问题已经有一个理由充分的 FAQ条目。但我也不期望它能消失,直到其他人通过努力去除它,并且显示GIL的去除不会减慢单线程Python代码的效率。

这在以前已经试过了,结果令人失望,这也是为什么我自已不愿意花太多精力的原因。在1999年Greg Stein(和Mark Hammond?)创建了一个去掉GIL(我相信是1.5)的分支,在所有可变数据结构上把GIL替换为细粒度锁。他也提交了补丁,可以去掉在全局可变数据结构上的许多信赖(reliance),我接受了。然而,做过了基准测试之后,它显示即使是在有着最快速的锁原语的平台上(当时是Windows)它减慢了单线程的执行效率将近2倍,意味着,与一颗CPU有GIL相比,不用GIL需要2颗CPU才能快一些。(参见Greg关于性能的 记录。)

我很欢迎如果有人按照Greg补丁(我在网上没有找到)的方法做了另外的试验,并且我也原意向Py3k引入一系列的补丁,但要保证对于单线程程序(和多线程但是I/O约束的程序)的性能不会降低。

我也会很高兴如果有人自告奋勇地维护一个无GIL的Python分支,假使单线程性能目标不能达到但是对于多线程CPU约束的应用有巨大的价值。我们甚至可以永久地终止部分代码基线的修改,仅仅允许根据编译的请求来生效。

然而,我想提醒一下,去掉GIL有许多的问题。它会使扩展模块变得复杂,不能再指望它们是在被GIL保护的“安全区”中被调用--一旦扩展有任何的全局可变数据,将不得不为多线程并发调用做好准备。也可能需要对Python/C API进行改动,它们是为了在一系列的调用中需要对某种对象加锁所需要的。

尽管这是我个人的意见,基于以上的考虑,去掉GIL没有太大的价值而不必花太多精力,但对于试图显示那个时代已经过去了的努力,我会欢迎和给予支持。然而,只是恳求是没有必要的--Python是开源的,并且我正在努力产生一个高质量的3.0语法的定义并且按计划实现。我想再一次指出并不是语言本身需要它--它只是由于CPython虚拟机在历史上还无法摆脱它。

原文链接
Python中的全局解释器锁(GIL)是为了保护Python字节码的解释器核心同时执行,防止多个线程并发修改数据结构而引入的。这意味着,在任何时候,只有一个线程能够执行Python字节码,即使是在多核处理器上也是如此。因此,尽管Python支持多线程,但它并适用于那些依赖大量CPU计算的任务(即CPU密集型),因为在这种情况下,线程切换频繁,CPU的实际利用率并没有提高。 如果你想要在Python中实现多线程,并且期望充分利用多核CPU,你需要关注以下几个方面: 1. **I/O密集型任务**:Python的`threading`库可以处理I/O密集型任务,因为在等待I/O响应时,GIL会被释放,其他线程可以执行。 2. **多进程**:Python的`multiprocessing`模块提供了一个无GIL的环境,因为它会启动新的进程,而是共享相同的解释器实例,所以理论上可以实现真正的并行计算。 3. **使用多线程池**:如`concurrent.futures.ThreadPoolExecutor`,它可以帮助管理线程池,将任务分发给各个线程,让它们在等待I/O操作时保持忙碌。 4. **利用第三方库**:有些第三方库,如Celery或multiprocessing.dummy,虽然底层还是基于线程,但由于其工作原理,可能能在某些场景下减轻GIL的影响。 需要注意的是,虽然以上措施可以在某种程度上提升性能,但要完全绕开GIL所带来的限制,可能需要采用更底层的技术,例如Cython扩展或使用Numba进行加速。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值