CPython中的全局解释器锁(GIL)是什么?
什么是全局解释器锁,为什么它会成为一个问题?
关于要不要把全局解释器锁(GIL)从Python中去掉,大家讨论得很热烈。我想知道这为什么这么重要。我自己从来没有写过编译器或解释器,所以请详细讲解,我可能需要这些细节来理解。
8 个回答
首先,我们来了解一下Python中的GIL(全局解释器锁)是干什么的:
在Python中,所有的操作和指令都是在解释器中执行的。GIL确保在某一时刻,解释器只能被一个线程占用。也就是说,当你用多个线程运行Python程序时,这些线程都是在同一个解释器里工作。在某一时刻,这个解释器只会被一个线程控制。这就意味着,只有持有解释器的那个线程在某一时刻是在运行的。
那么,这有什么问题呢:
你的电脑可能有多个核心或处理器,而多个核心可以让多个线程同时执行,也就是说,多个线程可以在某一时刻同时运行。但由于解释器只能被一个线程占用,其他线程即使可以使用核心,也无法执行任何操作。因此,你无法利用多个核心的优势,因为在任何时刻,只有一个核心在工作,这个核心就是当前持有解释器的线程所使用的。所以,你的程序执行的时间就像是单线程程序一样。
不过,有一些可能会阻塞或者运行时间较长的操作,比如输入输出(I/O)、图像处理和NumPy的数值计算,这些操作是在GIL之外进行的。根据这里的说法,对于这些操作来说,多线程的执行速度仍然会比单线程快,尽管有GIL的存在。所以,GIL并不总是一个瓶颈。
补充一下:GIL是CPython的一个实现细节。IronPython和Jython没有GIL,所以在这些环境中,真正的多线程程序是有可能实现的,不过我自己没有使用过PyPy和Jython,所以不太确定。
假设你有多个线程,它们之间的数据其实并没有太多交集。这些线程应该尽量独立地运行。如果你需要一个“全局锁”,也就是说在调用某个函数之前必须先获得这个锁,这样就可能会造成瓶颈。这样一来,你可能根本得不到使用多个线程的好处。
用一个现实生活中的比喻来说明:想象一下有100个开发者在一家公司工作,但只有一个咖啡杯。大多数开发者会花很多时间在等咖啡,而不是在写代码。
这些内容并不是专门针对Python的——我也不知道Python最初为什么需要一个全局锁。不过,希望这能让你对这个概念有个更清晰的理解。
Python中的GIL(全局解释器锁)是为了让不同线程在访问解释器内部时能够有序进行。简单来说,在多核系统上,这意味着多个线程不能有效地利用多个核心。(如果GIL没有导致这个问题,大多数人也不会在意它——之所以提到GIL,是因为多核系统越来越普遍。)如果你想更详细地了解这个问题,可以看看这个视频或者查看这组幻灯片。虽然信息可能有点多,但毕竟你是想了解更多的嘛 :-)
需要注意的是,Python的GIL主要是CPython这个参考实现的问题。Jython和IronPython是没有GIL的。作为一个Python开发者,通常情况下你不会碰到GIL,除非你在写C扩展。C扩展的开发者需要在扩展进行阻塞I/O时释放GIL,这样Python进程中的其他线程才能有机会运行。