Python GIL(Global Interpreter Lock) 核心意思就是,无论你启多少个线程,你有多少个cpu, Python在执行的时候会淡定的在同一时刻只允许一个线程运行,擦。。那这还叫什么多线程呀?莫如此早的下结论,听我现场讲。 首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。有名的编译器例如GCC,INTEL C++,Visual C++等。Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行。像其中的JPython就没有GIL。然而因为CPython是大部分环境下默认的Python执行环境。所以在很多人的概念里CPython就是Python,也就想当然的把GIL归结为Python语言的缺陷。所以这里要先明确一点:GIL并不是Python的特性,Python完全可以不依赖于GIL 来源: http://www.cnblogs.com/alex3714/articles/5230609.html
Python多线程是单cpu意义上的多线程,它和多cpu上的多线程有着本质的区别。 单cpu多线程:并发多cpu多线程:并行内部包含并发 在Python 多线程当中,存在一个叫 Global Interpreter Lock(GIL)的东西,直译就是全局解释器锁。它的作用在于让同一时刻只能有一个线程对于python对象进行操作。 1、Python已经提供了各种机制让我们进行多线程同步,为什么又要整这个GIL呢? 因为程序员控制的同步是对各个程序中可见的变量,而GIL同步的是解释器后台的不可见变量,比如为了进行垃圾回收而维护的引用计数。 如果没有GIL,有可能出现由于线程切换导致的对同一个对象释放两次的情况。 2、因此,任何一个CPython线程如果要执行,就必须先获取这个GIL。后果? 就是在CPython中,本质上几乎是没有线程并行的,不论你开多少个线程,同一时刻只有获取GIL的那个线程能够执行。为什么要说几乎呢, 这是因为提供给python的C库中,还是有解决方案的: 比如:这段代码是sleep的代码,在执行sleep之前,通过一个宏来释放GIL,然后在睡眠结束执行其他代码前又获取GIL。其他一下操作, 比如:IO,也会有类似的操作,这样就使得对于IO密集型的程序,或者是使用C库进行计算的程序,还是可以在很大程度上避开GIL来取得线程并行的效果的。但对于纯 python代码的程序,GIL恐怕还是躲不过去的。 3、还有一个问题,就是GIL怎么释放,我们看到在python/C API中提供了宏来进行释放,那么对于普通的python语句呢? 答案:解释器会在执行一百条python代码后强制释放GIL,这就使得其它线程得以执行。 最后需要说明的,就是这个GIL的问题是解释器相关的,而不是语言相关的。也就是说它只是对于python语言解释器的一种实现,并不是语言本身的特性。 事实上,GIL就是解释器的一个非常粗粒度的锁,我们完全可以采用更细粒度的锁来增加并行性,而且Gindo就写过一个patch来取消 GIL, 不过好像最后的结果是细粒度锁导致了单线程程序的性能下降了两倍,所以最后还是决定优先保证单线程程序的性能,继续保留GIL。 但是python 的其他两个分支,Jython和IronPython,却都没有GIL的问题,从而可以实现线程的并行。 总结: 通常加锁也有2种不同的粒度的锁: fine-grained(所谓的细粒度), 那么程序员需要自行地加(自己加锁),解锁来保证线程安全。 coarse-grained(所谓的粗粒度), 那么语言层面本身维护着一个全局的锁机制(GIL),用来保证线程安全 Python 多线程 从语言层面本身维护着一个全局的锁机制,用来保证线程安全;而java, Jython则是细粒度的。 所以也就是说,由于gil的限制,python语言本身是不能够进行并行编程的,但是可以进行并发编程;而java则没有gil意义上的限制, 因此java从java7开始已经开始往并行上偏移了。
时间: 2024-10-12 10:19:48