編程語言分類概念介紹(編譯型語言、解釋型語言、靜態類型語言、動態類型語言概念與區別)
https://www.cnblogs.com/zhoug2020/p/5972262.html
Python解釋器
一般使用的Python解釋器CPython:是用C語言實現Pyhon,是目前應用最廣泛的解釋器。最新的語言特性都是在這個上面先實現,基本包含了所有第三方庫支持,但是CPython有幾個缺陷,一是全局鎖使Python在多線程效能上表現不佳,二是CPython無法支持JIT(Just-in-time compliation即時編譯),導致其執行速度不及Java和Javascipt等語言。於是出現了Pypy。
Pypy:是用Python自身實現的解釋器。針對CPython的缺點進行了各方面的改良,性能得到很大的提升。最重要的一點就是Pypy集成了JIT。但是,Pypy無法支持官方的C/Python API,導致無法使用例如Numpy,Scipy等重要的第三方庫。(還有JPython,IronPython等)
全局解釋器鎖
全局解釋器鎖(Global Interpreter Lock)是Python用於同步線程的工具,使得任何時刻僅有一個線程在執行。
Python GIL被動釋放機制(搶占機制)
如果一個線程不間斷地在 Python 2 中運行100次解釋器的計步(ticks)(可以通過sys.setcheckinterval()設置計步長度),或者不間斷地在 Python 3 運行15 毫秒,那么它便會放棄 GIL,而其他線程可以運行。
全局解釋器鎖帶來的問題
多線程Python程序無法充分利用多個CPU核心帶來的優勢。
(主要影響CPU密集型程序,I/O密集型程序使用多線程一般是明智的選擇)
解決方法
1,使用多進程
原理:每個進程分配不同的解釋器,有單獨的GIL。
缺點:額外產生數據序列化與通信的開銷。
注意點:待執行操作需包含在以def語句定義的Python函數中(即,在這里lambda,閉包,可調用實例都是不可以的),而且函數參數和返回值必須兼容pickle編碼。
使用方法:廖雪峰Python教程-多進程部分
2,使用C語言擴展模塊
原理:C語言擴展程序的執行保持與Python解釋器隔離,在C代碼中釋放GIL。
缺點:調用C函數時GIL會被鎖定,若阻塞,解釋器無法釋放GIL。
注意點:確保C代碼可以獨立於Python執行。(不使用Python的數據結構,也不調用Python的C語言API)
使用方法:在C代碼中插入特殊的宏或是使用其他工具來訪問C代碼,如ctypes庫或者Cython。(ctypes默認會在調用C代碼時自動釋放GIL)
3,選用其他沒有GIL的解釋器代替CPython
原理:使用沒有GIL的解釋器實現。
缺點:不完全兼容。
使用方法:目前Jython和IronPython沒有GIL。