python和c混合编程 gil_终于搞明白python与gil
感想:東看一篇文章西看一篇文章,終于把gil的概念理順了
我們都知道,比方我有一個4核的CPU,那么這樣一來,在單位時間內每個核只能跑一個線程,然后時間片輪轉切換。但是Python不一樣,它不管你有幾個核,單位時間多個核只能跑一個線程,然后時間片輪轉。看起來很不可思議?但是這就是GIL搞的鬼。任何Python線程執行前,必須先獲得GIL鎖,然后,每執行100條字節碼,解釋器就自動釋放GIL鎖,讓別的線程有機會執行。這個GIL全局鎖實際上把所有線程的執行代碼都給上了鎖,所以,多線程在Python中只能交替執行,即使100個線程跑在100核CPU上,也只能用到1個核。通常我們用的解釋器是官方實現的CPython,要真正利用多核,除非重寫一個不帶GIL的解釋器
gil:全局解釋器鎖
存在原因:
早期設計python解釋器時是單核時代,并沒有考慮多核cpu情況
1.python的是使用引用計數的,當變量的引用計數為0就會被垃圾回收機制回收
2.python是解釋型語言,默認的解析器cpython是將python語言翻譯成c,再調用c函數實現執行python程序
3.線程與進程不同,是共享用戶地址空間的,也就是共享全局變量
綜上,如果同一個時刻有兩個線程執行,那么全局變量的引用計數可能同時從0變成1,最終它的引用計數就是1,而卻有兩個線程在使用它,這顯然是不對的.
解釋:
全局:針對全局資源/同一個時刻,不管有多少個核,都只有一個線程能使用cpu資源
解釋鎖:cpython鎖(C語言實現的Python解釋器)
為什么java沒有gil鎖呢?
java實現了顆粒度更小的鎖,而程序的執行順序是:獲取鎖-執行程序-釋放鎖,所以增加了獲取和釋放鎖的資源開銷,所以全局鎖這一把大鎖其實也有好處,切換線程的資源浪費較少.
解釋器怎么切換線程?
如果是純計算的程序,沒有 I/O 操作,解釋器會每隔100次操作就釋放這把鎖,讓別的線程有機會 執行(這個次數可以通sys.setcheckinterval來調整)同一時間只會有一個獲得GIL線程在跑,其他線程都處于等待狀態
哪種任務適合用多線程?
1、如果是CPU密集型代碼(循環、計算等),由于計算工作量多和大,計算很快就會達到100,然后觸發GIL的釋放與在競爭,多個線程來回切換損耗資源,所以在多線程遇到CPU密集型代碼時,單線程會比較快
2、如果是I\O密集型代碼(文件處理、網絡爬蟲),開啟多線程實際上是并發(不是并行),IO操作會進行IO等待,線程A等待時,自動切換到線程B,這樣就提升了效率
怎么優化?
1.改用多進程,多個Python進程有各自獨立的GIL鎖
2.將計算代碼轉成c代碼,使用調用c代碼的接口,將cpu密集型任務切換成io任務:對所有面向I/O的(會調用內建的操作系統C代碼的)程序來說,GIL會在這個I/O調用之前被釋放,以允許其他線程在這個線程等待I/O的時候運行。我們可以把一些 計算密集型任務用C語言編寫,然后把.so鏈接庫內容加載到Python中,因為執行C代碼,GIL鎖會釋放
與多進程使用變量的區別:
多進程:linux系統里面,fork出來的進程,其變量與源進程相同,如果只做讀取,那么不會內存分配,如果發生寫入,那么創建新內存頁
缺點?
導致python無法實現真正意義上的多線程
Java吧 收集整理 java論壇 www.java8.com
總結
以上是生活随笔為你收集整理的python和c混合编程 gil_终于搞明白python与gil的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 灵图天行者9 pc版_原神PC预下载现已
- 下一篇: 阿里云python面试题_Python金