1. 程式人生 > 程式設計 >Cpython直譯器中的GIL全域性直譯器鎖

Cpython直譯器中的GIL全域性直譯器鎖

1、什麼是GIL全域性直譯器鎖

  GIL:Global Interpreter Lock,意思就是全域性直譯器鎖,這個GIL並不是Python的特性,他是隻在Cpython直譯器裡引入的一個概念,而在其他的語言編寫的直譯器裡就沒有GIL,例如:Jython,Pypy等

  下面是官方給出的解釋:

In CPython,the global interpreter lock,or GIL,is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython's memory management is not thread-safe. (However,since the GIL exists,other features have grown to depend on the guarantees that it enforces.)

  翻譯過來的意思就是:在CPython中,全域性直譯器鎖(GIL)是一個互斥鎖,可以防止多個本地執行緒同時執行Python位元組碼。這個鎖是必要的,主要是因為CPython的記憶體管理不是執行緒安全的。(但是,由於GIL存在,其他特性已經發展到依賴於它所執行的保證。)

  所以:

    GIL本質上就是一把互斥鎖,用來保證資料的正確性,使資料可以正常同步。

    GIL就像是BUG一般存在的全域性互斥鎖,目前無法通過程式碼去除GIL

  結論:在CPython直譯器中,在同一個程序下開啟的多執行緒,同一時刻只能有一個執行緒執行,無法利用多核優勢

  PS:我們平常所使用的python是C語言編寫的,所以大部分人所說的python也指CPython,CPython是python的官方版本,若是指其他語言寫的python,一般情況下會指明,如Jypthon、Pypy等

2、為什麼會出現GIL

  隨著電腦多核CPU的出現,python為了充分利用多核CPU,進行多執行緒的程式設計方式便普及了起來,但是隨之而來的困難是執行緒之間資料的一致性和狀態同步,python為了解決這個資料不能同步的問題,所以設計了GIL全域性直譯器鎖,其實就是互斥鎖

  說到互斥鎖,在多執行緒互斥鎖中共享全域性變數的時候會有執行緒對全域性變數進行的資源競爭,會對全域性變數的修改產生不是我們想要的結果,而那個時候用到的是python中執行緒模組裡面的互斥鎖。

  如下例(未加執行緒互斥鎖):

from threading import Threadimport time


n = 100
def task():
  global n
  m = n
  time.sleep(0.5)  # 模擬IO操作
  n = m - 1


if __name__ == '__main__':
  list1 = []
  for i in range(10):
    t = Thread(target=task)
    t.start()
    list1.append(t)

  for t in list1:
    t.join()

  print(n)

 執行結果:

99

  在上面的例子裡,我建立了10個執行緒來爭奪對 n 進行 -1 操作,但是結果並非我想要的,所以我在這裡加入了互斥鎖

  如下例(加執行緒互斥鎖):

from threading import Thread
from threading import Lock
import time


n = 100
def task(lock):
  global n
  lock.acquire()  # 加鎖
  m = n
  time.sleep(0.5)  # 模擬IO操作
  n = m - 1
  lock.release()  # 解鎖


if __name__ == '__main__':
  list1 = []
  lock = Lock()
  for i in range(10):
    t = Thread(target=task,args=(lock,))
    t.start()
    list1.append(t)

  for t in list1:
    t.join()

  print(n)

  執行結果:

90

  這次就可以得到我想要的結果

3、GIL的優缺點

  優點:

    保證資料的正確性

  缺點:

    單個程序下,開啟多個執行緒,犧牲了執行效率,無法實現並行,只能實現併發

4、如何體現GIL全域性直譯器鎖

  在Cpython直譯器中,當python程式碼有一個執行緒開始訪問直譯器的時候,GIL會把這個大鎖給鎖上,此時此刻其他的執行緒只能乾等著,無法對直譯器的資源進行訪問,這一點就和互斥鎖相似。而只是這個過程發生在我們的Cpython中,同時也需要等這個執行緒分配的時間到了,這個執行緒把GIL釋放掉,類似互斥鎖的lock.release()一樣,另外其他的執行緒才開始跑起來。

Cpython直譯器中的GIL全域性直譯器鎖

以上就是Cpython直譯器中的GIL全域性直譯器鎖的詳細內容,更多關於GIL全域性直譯器鎖的資料請關注我們其它相關文章!