1. 程式人生 > >多線程與CPU和多線程與GIL

多線程與CPU和多線程與GIL

程序 數據完整性 多核 nbsp 對象 解釋器 一是 IT 數量

多線程與CPU:
1.單核CPU CPU密集型的程序(做計算操作的程序) 單線程即可( 此時的任務已經把CPU資源100%消耗了,就沒必要也不可能使用多線程來提高計算效率)
2.單核CPU IO密集型的程序(做IO操作的程序 ) 多線程>單線程(多線程可以阻塞,但並不是並行,是“偽並行”,實際上還是一個CPU在執行一切事物,只是切換的太快,沒法察覺)
3.多核CPU 做計算操作的程序 多線程>>單線程 (每個核心執行一個線程,每個核心的線程並發執行計算,以提高任務執行效率,例如加密解密,數據壓縮解壓縮(視頻、音頻、普通數據),否則只能使一個核心滿載,而其他核心閑置。)

4.多核CPU IO密集型任務 多線程>單線程

但是在PYTHON裏:

由於GIL的機制就變得不完全一樣了:單核CPU CPU密集型程序 單線程耗時<多線程。多核CPU CPU密集型程序 單線程耗時<多線程,也就是說只要是CPU密集型程序 不要只單獨的使用多線程。

一、先說為什麽會有GIL ,GIL是幹什麽的:

多線程之間數據完整性和狀態同步的最簡單方法自然就是加鎖,於是python解釋器有了GIL這把超級大鎖,就默認python內部對象是thread-safe的,無需在實現時考慮額外的內存鎖和同步操作。

也就是說 如果不釋放這把鎖,線程都是串行的。

但PYTHON的多線程並不是一無是處

二、GIL鎖的釋放機制:

IO密集型:
線程遇到I/O阻塞時,會自動釋放GIL。(阻塞等待時,就釋放GIL,給另一個線程執行的機會)

cpu密集型:
解釋器會周期性的讓線程釋放鎖

由上面可知,至少有兩種情況python會做線程切換,一是一但有IO操作時,會有線程切換,二是當一個線程連續執行了一定數量的指令時,會出現線程切換。

再加上每次操作系統執行線程的調度都需要消耗時間,這樣,就可以理解為什麽在多核+cpu密集型程序時不要單獨的使用多線程,會比單線程更耗時。

即使是多核CPU,如果沒有GIL 不同核的CPU執行不同的線程,但是有了GIL這把鎖,某個核心上的CPU即使被喚醒也沒有獲得GIL鎖,無法執行。

綜上,在不使用別的庫的情況下,python多線程最好只用於IO密集型的操作。

參考:https://blog.csdn.net/delacroix_xu/article/details/5928121

http://cenalulu.github.io/python/gil-in-python/

多線程與CPU和多線程與GIL