python里的多线程是单cpu意义上的多线程

python里的多线程是单cpu意义上的多线程,它和多cpu上的多线程有着本质的区别。
单cpu多线程:并发
多cpu多线程:并行内部包含并发
在python当中,存在一个叫Global Interpreter Lock(GIL)的东西,直译就是全局解释器锁。它的作用在于让同一时刻只能有一个线程对于python对象进行操作。Python已经提供了各种机制让我们进行多线程同步,为什么又要整这个GIL呢?这是因为程序员控制的同步是对各个程序中可见的变量,而GIL同步的是解释器后台的不可见变量,比如为了进行垃圾回收而维护的引用计数。如果没有GIL,有可能出现由于线程切换导致的对同一个对象释放两次的情况。


因此,任何一个CPython线程如果要执行,就必须先获取这个GIL。后果?就是在CPython中,本质上几乎是没有线程并行的,不论你开多少个线程,同一时刻只有获取GIL的那个线程能够执行
为什么要说几乎呢,这是因为提供给python的C库中,还是有解决方案的
...
Py_begin_allow_threads
sleep((int)secs);
Py_end_allow-threads
...
这段代码是sleep的代码,在执行sleep之前,通过一个宏来释放GIL,然后在睡眠结束执行其他代码前又获取GIL。其他一下操作,比如IO,也会有类似的操作,这样就使得对于IO密集型的程序,或者是使用C库进行计算的程序,还是可以在很大程度上避开GIL来取得线程并行的效果的。但对于纯python代码的程序,GIL恐怕还是躲不过去的。
还有一个问题,就是GIL怎么释放,我们看到在python/C API中提供了宏来进行释放,那么对于普通的python语句呢?解释器会在执行一百条python代码后强制释放GIL,这就使得其它线程得以执行
最后需要说明的,就是这个GIL的问题是解释器相关的,而不是语言相关的。也就是说它只是对于python语言解释器的一种实现,并不是语言本身的特性。事实上,GIL就是解释器的一个非常粗粒度的锁,我们完全可以采用更细粒度的锁来增加并行性,而且Gindo就写过一个patch来取消GIL,不过好像最后的结果是细粒度锁导致了单线程程序的性能下降了两倍,所以最后还是决定优先保证单线程程序的性能,继续保留GIL。但是python的其他两个分支,Jython和IronPython,却都没有GIL的问题,从而可以实现线程的并行。为什么呢?这里也不知道原因了。


python追求的是简单和简洁.在代码中加入多线程往往都是一件简单的事情.这违背了python里面的蝉.提供了多线程不代表他就是常规理解的多线程.和ruby一样,ruby也提供了多线程但是确实伪线程.


1. 准确的说,只有获得了GIL的线程可以执行Python ByteCode,也就是说,Python ByteCode不能并行在多核上运行。但是Python里有大量的C代码,这些代码可以不受GIL的限制。
2. 谁说并行一定要多线程?早在没有线程那会儿Unix甚至Windows就并行的好好的了,连DOS下都有TSR。就算是纯Python,你一样可以用multiprocess做并行,一样能把CPU跑满。


java,就不说了。开始设计就要求是多线程的,而且java的多线程是java不能实现完整跨平台一个重要因素(线程的优先级在不同操作系统表现的不一样)

你可能感兴趣的:(python里的多线程是单cpu意义上的多线程)