圍繞全域性直譯器鎖(GIL)工作

為什麼有 GIL?

自 1992 年 Python 執行緒開始以來,GIL 一直在 CPython 中出現。它旨在確保執行 python 程式碼的執行緒安全性。使用 GIL 編寫的 Python 直譯器可防止多個本機執行緒同時執行 Python 位元組碼。這使得外掛可以輕鬆確保其程式碼是執行緒安全的:只需鎖定 GIL,只有你的活動執行緒能夠執行,因此你的程式碼自動是執行緒安全的。

簡短版本:GIL 確保無論你擁有多少處理器和執行緒,一次只能執行一個 python 直譯器的一個執行緒。

這有很多易用的好處,但也有很多負面的好處。

請注意,GIL 不是 Python 語言的要求。因此,你無法直接從標準 python 程式碼訪問 GIL。並非所有 Python 實現都使用 GIL。

有 GIL 的直譯器: CPython,PyPy,Cython(但你可以用 nogil 禁用 GIL)

沒有 GIL 的譯員: Jython,IronPython

有關 GIL 如何運作的詳細資訊:

當執行緒正在執行時,它會鎖定 GIL。當執行緒想要執行時,它會請求 GIL,並等待它可用。在 CPython 中,在版本 3.2 之前,正在執行的執行緒將檢查一定數量的 python 指令,以檢視其他程式碼是否需要鎖定(即,它釋放了鎖,然後再次請求它)。這種方法往往導致執行緒飢餓,主要是因為釋放鎖的執行緒會在等待執行緒有機會喚醒之前再次獲取它。從 3.2 開始,希望 GIL 的執行緒等待鎖定一段時間,之後,它們設定了一個共享變數,迫使正在執行的執行緒產生。但是,這仍然會導致執行時間大幅延長。有關詳細資訊,請參閱 dabeaz.com(參考部分)中的以下連結。

當執行緒執行 I / O 操作時,CPython 會自動釋放 GIL。影象處理庫和 numpy 數字運算操作在執行處理之前釋放 GIL。

GIL 的好處

對於使用 GIL 的直譯器,GIL 是系統性的。它用於保留應用程式的狀態。好處包括:

  • 垃圾收集 - 在 GIL 鎖定時必須修改執行緒安全引用計數。*在 CPython 中,所有的 garbarge 集合都與 GIL 相關聯。*這是一個很大的問題; 請參閱有關 GIL 的 python.org wiki 文章(在下面的參考文獻中列出),以獲取有關如果想刪除 GIL 必須仍然可用的內容的詳細資訊。
  • 易於處理 GIL 的程式設計師 - 鎖定一切都很簡單,但很容易編碼
  • 簡化從其他語言匯入模組的過程

GIL 的後果

GIL 只允許一個執行緒在 python 直譯器中一次執行 python 程式碼。這意味著執行嚴格 python 程式碼的程序的多執行緒不起作用。在針對 GIL 使用執行緒時,執行緒的效能可能比在單個執行緒中執行時差。

參考文獻:

https://wiki.python.org/moin/GlobalInterpreterLock - 它的功能快速摘要,所有好處的詳細資訊

http://programmers.stackexchange.com/questions/186889/why-was-python-written-with-the-gil - 寫得很清楚

http://www.dabeaz.com/python/UnderstandingGIL.pdf - GIL 如何工作以及為什麼它會減慢多核心的速度

http://www.dabeaz.com/GIL/gilvis/index.html - 顯示 GIL 如何鎖定執行緒的資料的視覺化

http://jeffknupp.com/blog/2012/03/31/pythons-hardest-problem/ - 簡單易懂 GIL 問題的歷史

https://jeffknupp.com/blog/2013/06/30/pythons-hardest-problem-revisited/ - 有關解決 GIL 限制的方法的詳細資訊