標籤:自動 效率 網路爬蟲 ret 耗資源 相同 rom 封裝 設計
進程:一個進程就是一個程式,進程可以使用多核CPU。
線程:進程裡面的最小的執行單元,幹活的是線程
一個進程裡面最少有一個線程(主線程),可以有多個線程(子線程)
線程之間是相互獨立的。主線程和子線程也是相互獨立的。
主線程會從頭到尾執行命令。不會等待子線程。子線程執行完以後就消了
多個線程操作一個資料的時候,最好加上鎖。
from threading import Lock
lock = Lock()
def run():
golbal num=0
lock.acquire() #加鎖
num+=1
lock.release() #解鎖
另一種寫法:with lock:
num+=1
守護線程:
守護線程就是和秦始皇陪葬的人一樣
主線程是秦始皇,子線程就是陪葬的人
沒有真正上的並發,你的電腦是幾核的,那最多隻能同時運行幾個任務。
python裡面的多線程,利用不了多核cpu,只能利用一個核心的cpu
有些情況下,用多線程比單線程速度還慢
python 為什麼不能利用多核 CPU
GIL 其實是因為在 python中有一個 GIL( Global Interpreter Lock),中文為:全域解譯器鎖。
1、最開始時候設計GIL是為了資料安全。python為了資料安全設計了這個 GIL。
2、每個 CPU在同一時間只能執行一個線程:
在單核 CPU下的多線程其實都只是並發,不是並行,並發和並行從宏觀上來講都是同時處理多路請求的概念。 但並發和並行又有區別,並行是指
兩個或者多個事件在同一時刻發生;而並發是指兩個或多個事件在同一時間間隔內發生)
在 python多線程下,每個線程的執行方式如下:
1、擷取GIL
2、執行代碼直到sleep或者是 python虛擬機器將其掛起。
3、釋放 GIL
為什麼有時候多線程效率低於單線程?
1、如上我們可以知道,在 python中想要某個線程要執行必須先拿到 GIL這把鎖,且 python只有一個 GIL,拿到這個 GIL才能進入 CPU執行, 在遇
到 I/O操作時會釋放這把鎖。如果是純計算的程式,沒有 I/O 操作,解譯器會每隔 100次操作就釋放這把鎖,讓別的線程有機會 執行(這個次數可以通
sys.setcheckinterval來調整)。所以雖然 CPython 的線程庫直接封裝作業系統的原生線程,但 CPython 進程做為一個整體,同一時間只會有一個獲得了
GIL 的線程在跑,其它的線程都處於等待狀態等著 GIL 的釋放。
2、而每次釋放 GIL鎖,線程進行鎖競爭、切換線程,會消耗資源。並且由於 GIL鎖存在,python裡一個進程永遠只能同時執行一個線程 (拿到 GIL的線
程才能執行 ),這就是為什麼在多核 CPU上, python的多線程效率並不高。
為什麼python的多線程利用不了多核cpu,那為什麼比單線程速度要快?
相同的代碼,為何有時候多線程會比單線程慢,有時又會比單線程快?
這主要跟啟動並執行代碼有關:
1、 CPU密集型代碼(各種迴圈處理、計數等等 ),在這種情況下,由於計算工作多, ticks計數很快就會達到 100閾值,然後觸發 GIL的釋放與再競
爭 (多個線程來回切換當然是需要消耗資源的),所以 python下的多線程遇到 CPU密集型代碼時,單線程比多線程效率高。
2、IO密集型代碼 (檔案處理、網路爬蟲等 ),多線程能夠有效提升效率
單線程下有 IO操作會進行 IO等待,造成不必要的時間浪費。
開啟多線程能線上程 A等待時,自動切換到線程 B,可以不浪費 CPU的資源,從而能提升程式執行效率 。
進行 IO密集型的時候可以進行分時切換 所有這個時候多線程快過單線程
如果 python想充分利用多核 CPU,可以採用多進程。
每個進程有各自獨立的 GIL,互不干擾,這樣就可以真正意義上的並存執行。
在 python中,多進程的執行效率優於多線程 (僅僅針對多核 CPU而言 )。所以在多核 CPU下,想做並行提升效率,比較通用的方法是使用多進程,能夠有效提高執行效率。
Python——線程和進程