什么是全局解释器锁,为什么它是一个问题?什么是全局解释器锁(GIL)?
大量的噪音,已经取得了从周围的Python去除GIL,我想知道为什么是如此的重要。我从来没有编写过编译器和解释器,所以不要因为细节而节俭,我可能需要他们去理解。
什么是全局解释器锁,为什么它是一个问题?什么是全局解释器锁(GIL)?
大量的噪音,已经取得了从周围的Python去除GIL,我想知道为什么是如此的重要。我从来没有编写过编译器和解释器,所以不要因为细节而节俭,我可能需要他们去理解。
Python的GIL旨在序列化来自不同线程的解释器内部的访问。在多核系统上,这意味着多线程无法有效利用多核。 (如果GIL没有导致这个问题,大多数人不会关心GIL--由于多核系统的普及程度越来越高,它只是被提出来作为一个问题。)如果你想详细了解它,您可以查看this video或查看this set of slides。这可能是信息太多了,但你没询问详情:-)
需要注意的是Python的GIL是唯一真正的CPython的,参考实现的问题。 Jython和IronPython没有GIL。作为Python开发人员,除非您正在编写C扩展,否则通常不会遇到GIL。 C扩展编写者需要在其扩展阻塞I/O时释放GIL,以便Python进程中的其他线程有机会运行。
更新:更新后的视频链接指向Youtube,因为之前的blip.tv
链接已经腐烂。
好的答案 - 基本上,这意味着Python中的线程只适用于阻止I/O;你的应用程序永远不会超过1个处理器使用的CPU核心 – 2009-08-18 15:26:29
“作为一名Python开发人员,除非你正在编写C扩展程序,否则通常不会遇到GIL” - 您可能不知道多线程的原因以蜗牛速度运行的代码是GIL,但你一定会感受到它的影响。令我惊讶的是,利用Python的32核心服务器意味着我需要32个进程以及所有相关的开销。 – Basic 2014-01-07 17:42:36
@PaulBetts:这是不正确的。性能关键代码很可能已经使用了可以释放GIL的C扩展,例如'regex','lxml','numpy'模块。 Cython允许在自定义代码中释放GIL,例如['b2a_bin(data)'](https://gist.github.com/zed/3526111) – jfs 2015-08-16 13:34:10
假设你有多个线程这不真的触摸对方的数据。那些应该尽可能地独立执行。如果你有一个“全局锁定”,你需要获取以便(称)调用一个函数,这可能最终成为一个瓶颈。首先,您可以从多线程中获益不多。
为了把它变成一个真正的世界类比:假如100个开发者在一个公司只有一个咖啡杯的工作。大多数开发者会花时间等待咖啡而不是编码。
无的,这是Python特定的 - 我不知道什么样的Python需要GIL在首位的细节。不过,希望它给你一个更好的概念概念。
但是,如果开发者在做票务支持,而不是(写作2 - 分钟回复,然后等待1小时),尽管只有一个咖啡杯,但他们都会很有成效。 – 2017-06-28 10:28:09
维基百科有一个全球性的解释的一个很好的说明锁
http://en.wikipedia.org/wiki/Global_Interpreter_Lock
这个漂亮的文章,讨论在Python的GIL那篇文章的链接。
可能最好链接到DDJ文章的开头部分 - http://www.ddj.com/linux-open-source/206103078 – 2009-08-18 15:02:19
谢谢,但我在做这个问题之前做了功课,当然还是去了谷歌和维基百科第一。 – 2009-08-18 15:02:47
当两个线程可以访问相同的变量,你有问题。 在C++中,避免此问题的方法是定义一些互斥锁,以防止两个线程同时进入对象的setter。
多线程是可能的在python中,但两个线程不能在同一时间执行 在粒度比一个python指令更精细。 正在运行的线程正在获取一个名为GIL的全局锁。
这意味着,如果你开始为了充分利用你的多核处理器的写一些多线程代码,你的表现也不会提高。 通常的解决方法包括进行多进程。
请注意,如果您使用C编写的方法,则可以释放GIL。
GIL的使用不是Python固有的,而是它的一些解释器,包括最常见的CPython。 (#edited,见注释)
的GIL问题仍然是有效的Python 3000
Stackless仍然有一个GIL。 Stackless不会改进线程(如在模块中) - 它提供了一种不同的编程方法(协程),它尝试侧重解决问题,但需要非阻塞函数。 – jnoller 2009-08-18 16:24:02
好点。感谢您的评论 – fulmicoton 2009-08-18 22:19:26
3.2中的新GIL如何? – new123456 2011-07-07 01:11:56
Watch David Beazley告诉你所有你想知道的一切GIL。
这是一篇长篇文章,讨论Python中的GIL和线程问题,我写了一段时间。它会进入一个相当数量的细节就可以了:
http://jessenoller.com/2009/02/01/python-threads-and-the-global-interpreter-lock/
nice info der !!!!!!!!!! thanx – vks 2016-01-21 08:18:29
让我们先了解一下Python的GIL提供:
的任何操作/指令的解释执行。 GIL确保解释者在的特定时刻由单个线程持有。而你的多线程python程序在一个解释器中工作。在任何特定的时刻,这个解释器都由一个单独的线程保存。这意味着只有拿着解释器的线程是运行在任何时刻。
现在为什么是一个问题:
您的机器可能在具有多个核心/处理器。多核允许多个线程同时执行即多个线程可以在任何特定时刻执行。。 但是由于解释器是由单个线程保存的,其他线程即使可以访问内核也不会做任何事情。因此,您没有获得多核心提供的任何优势,因为在任何时候,只有一个核心(目前正在使用该解释程序的线程使用的核心)正在被使用。所以,你的程序需要很长时间来执行,就好像它是一个单线程程序一样。
但是,潜在的阻塞或长时间运行的操作(例如I/O,图像处理和NumPy数字运算)发生在GIL之外。取自here。因此,对于这样的操作,尽管存在GIL,但多线程操作仍然比单线程操作更快。所以,GIL并不总是一个瓶颈。
编辑:GIL是CPython的实现细节。 PyPy和Jython没有GIL,所以一个真正的多线程程序应该是可能的,我认为我从来没有使用PyPy和Jython,并且不确定这一点。
** Note **: PyPy有** GIL **。_参考:[http://doc.pypy.org/en/latest/faq.html#does-pypy-have-a-gil-why](http://doc.pypy .org/en/latest/faq.html#does-pypy-have-a-gil-why)。虽然Ironpython和Jython没有GIL。 – 2016-06-08 06:27:36
确实,PyPy有一个GIL,但IronPython没有。 – Emmanuel 2018-01-17 14:47:48
下面是一些代码演示GIL的影响:https://github.com/cankav/python_gil_demonstration
为什么的Python(CPython的和其他人)使用GIL
从http://wiki.python.org/moin/GlobalInterpreterLock
在CPython中,全局解释锁,或GIL是一个互斥体,可以防止多个本地线程一次执行Python字节码。这个锁主要是因为CPython的内存管理不是线程安全的。
如何从Python中删除它?
就像Lua一样,也许Python可以启动多个虚拟机,但是python没有这样做,我想应该有其他一些原因。
在Numpy或其他一些Python扩展库中,有时将GIL释放到其他线程可能会提高整个程序的效率。
我想分享本书多线程Visual Effects的示例。因此,这里是一个典型的死锁情况
static void MyCallback(const Context &context){
Auto<Lock> lock(GetMyMutexFromContext(context));
...
EvalMyPythonString(str); //A function that takes the GIL
...
}
现在考虑的序列中产生的死锁的事件。
╔═══╦════════════════════════════════════════╦══════════════════════════════════════╗
║ ║ Main Thread ║ Other Thread ║
╠═══╬════════════════════════════════════════╬══════════════════════════════════════╣
║ 1 ║ Python Command acquires GIL ║ Work started ║
║ 2 ║ Computation requested ║ MyCallback runs and acquires MyMutex ║
║ 3 ║ ║ MyCallback now waits for GIL ║
║ 4 ║ MyCallback runs and waits for MyMutex ║ waiting for GIL ║
╚═══╩════════════════════════════════════════╩══════════════════════════════════════╝
我觉得这是GIL最好的解释。请阅读。
的Python不允许在这个词的真正意义上的多线程。它有一个多线程包,但如果你想用多线程来加速你的代码,那么使用它通常不是一个好主意。 Python有一个叫做Global Interpreter Lock(GIL)的构造。 GIL确保只有一个'线程'可以在任何时候执行。线程获取GIL,做一些工作,然后将GIL传递到下一个线程。这种情况发生得非常快,所以对于人眼而言,它可能看起来像你的线程并行执行,但它们实际上只是轮流使用相同的CPU内核。所有这些GIL通过都会增加执行的开销。这意味着如果你想让你的代码运行得更快,那么使用线程包通常不是一个好主意。
有理由使用Python的线程包。如果你想同时运行一些东西,而且效率不是问题,那么它就非常好,很方便。或者如果你正在运行需要等待某些事情的代码(比如一些IO),那么它可能会很有意义。但线程库不会让你使用额外的CPU核心。多线程可以外包给操作系统(通过执行多处理),某些调用Python代码的外部应用程序(例如Spark或Hadoop)或一些代码(Python代码)(例如:你可以让你的Python代码调用一个执行昂贵的多线程的C函数)。
可能重复的[Why the Global Interpreter Lock?](http://stackoverflow.com/questions/265687/why-the-global-interpreter-lock) – 2015-09-10 10:03:42