python高級語法——(1)GIL學習

GIL(全局解析器鎖)

GIL,全局解析器鎖,只對多線程有影響。
如果沒有GIL,多線程會同時調用全局資源,全局資源會因多個線程同時調用而造成數據錯誤。
因此每個線程在執行過程中都需要先獲取GIL,保證同一時刻只有一個線程在執行代碼,這樣纔不會造成數據錯誤。

多線程並不是真正“多線程”的例子
  • 單進程下的CPU利用率
    下面代碼保存爲single_thread.py,同時運行兩個single_thread.py,兩個程序各佔滿兩個CPU核心,CPU利用率爲100%。
# 主進程死循環,佔用整個CPU
def single_thread():
    while True:
        pass

test()
  • 多線程下的CPU利用率
    下面代碼保存爲multithreading.py ,運行後發現,單進程內雙線程即使同時死循環,兩個核心中的CPU資源利用率都僅爲50%。可以認爲實際上只有一個核佔滿資源,和單線程沒區別。
import threading


# 子進程死循環
def test_thread1():
    while True:
        pass


t1 = threading.Thread(target=test_thread1)
t1.start()


# 主進程死循環
def test_thread2():
    while True:
        pass


test_thread2()
  • 多進程下的CPU利用率
    下面代碼保存爲multiprocessing.py,運行後發現CPU中兩個核心的資源利用率爲100%。
import multiprocessing


# 子進程
def test_multiprocessing1():
    while True:
        pass


m1 = multiprocessing.Process(target=test_multiprocessing1)
m1.start()


# 主進程
def test_multiprocessing2():
    while True:
        pass


test_multiprocessing2()

總結:多線程在死循環的程序中也不會導致CPU滿資源的原因是GIL。全局解析器鎖GIL的存在會限制多線程在運行中,實際僅有一個線程在執行任務。

  • GIL不是python語言的問題,是python解析器的問題,cpython(C語言寫的解析器)中存在這樣的問題;
  • 因此如果用的是cpython解析器,想要發揮多核性能,應該使用多進程;如果是其他解析器,多線程也能發揮多核性能;
  • 爬蟲程序中,多線程比單線程性能用提升,因爲在遇到IO阻塞會自動釋放GIL鎖。
計算密集型程序和IO密集型程序
  • 計算密集型
    計算密集型程序,多用於計算和分析等領域的程序,GIL在這種程序中是個累贅,多線程等於單線程;

    多進程沒GIL的影響,因此多進程適合計算密集型程序

  • IO密集型
    IO,input和output輸入輸出類型,程序中常出現阻塞,計時等需要耗時的情況,GIL能在線程阻塞時自動釋放GIL鎖,其他線程就能執行代碼,形成多線程併發的假象;

總結:多線程適用於IO密集型程序

用C語言解決GIL鎖問題

多線程任務用C語言編寫,通過在python代碼中導入C語言文件解決多線程中GIL的問題

  • 下面代碼保存爲deadloop.c文件
void DeadLoop(){
    while(1){
        ;
    }
}
  • 通過gcc 文件名.c -shared -o lib文件名.so編譯後得到libdeadloop.so動態庫文件
  • 將下面代碼保存爲solution.py文件,文件中加載了libdeadloop.so動態庫中的DeadLoop()函數作爲子線程
from ctypes import *
import threading

# 加載動態庫libdeadloop
lib = cdll.LoadLibrary("./libdeadloop.so")

# 創建一個子線程,加載動態庫中的DeadLoop()函數,此函數是一個死循環
t = threading.Thread(target=lib.DeadLoop)
t.start()


# 主線程
def multi_threading2():
    while True:
        pass


multi_threading2()

總結:此時運行solution.py文件,多線程中爲兩個死循環,佔用的CPU資源比爲100%,證明解決了GIL鎖線程的問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章