1. 程式人生 > >python中多執行緒排程機制以及GIL

python中多執行緒排程機制以及GIL

總結下python中執行緒排程機制. 對於執行緒排程機制而言,同作業系統的程序排程一樣,最關鍵是要解決兩個問題: 1.在何時選擇掛起當前執行緒,並選擇處於等待的先一個執行緒呢? 2.在眾多等待的執行緒中,選擇哪一個作為啟用執行緒呢? 在python多執行緒機制中,這個兩個問題是有兩個層次解決的。 如,程序間的切換,當發生了時鐘中斷,作業系統響應時鐘中斷,並在這個時候開始程序的排程。 同樣的,python也是通過軟體模擬了這樣的時鐘中斷,來激啟用執行緒的排程。 我們知道,python位元組碼直譯器是按照指令,順序一條一條地執行。這就可以在python內部維護一個數值,即就是時鐘。如果為N,即當執行了N條指令後,就應該立即啟動執行緒排程機制。 import sys sys.getcheckinterval() 同時也可以通過sys.setcheckinterval()來調節這個值。 那麼接下來,python該在等待的執行緒中選擇哪一個執行呢? 答案是:不知道。 因為python完全沒有插手。 由於python是建立在作業系統的原生執行緒上,所以這樣頭大的事情就交給作業系統吧。由於不同作業系統的排程機制不一樣,故,python提供了一層抽象機制,即  thread(c 實現)以及在其之上的threading(python實現)。  multiprocessing ?? python執行緒的建立。 通過原始碼分析,主要完成三個動作: 1.建立並初始化bootstate的結構體 boot,在boot中,將儲存關於執行緒的一切資訊,如,執行緒過程,執行緒過程的引數。 2.初始化python的多執行緒環境。(建立GIL) 3.以boot為引數,建立作業系統的原生執行緒。 特別說明:python啟動時,是並不支援多執行緒的,換句話說,python的多執行緒的資料結構以及GIL都是沒有建立的,這樣做,是因為python程式碼,大部分都不需要多執行緒的支援。 因為對多執行緒的支援是有一定代價的:如果激活了多執行緒機制,而執行的python程式中沒有用到多執行緒,那麼在100條指令之後,python虛擬機器同樣會啟用執行緒的排程。這樣就多了一些無用功。
所以,python就把這些留給使用者方便、靈活地去控制了。 GIL是什麼? 看看原始碼的主要定義,及其初始化: typedef struct NRMUTEX {     LONG owned;     DWORD thread_id;     HANDLE hevent; } NRMUTEX, *PNRMUTEX; BOOL InitializeNonRecursiveMutex(PNRMUTEX mutex) {     mutex->owned = -1;     mutex->thread_id = 0     mutex->hevent = CreateEvent(NULL, FALSE, FALSE, NULL)
    return mutex->hevent != NULL;// True if the mutex is created