python中多執行緒排程機制以及GIL
阿新 • • 發佈:2019-02-06
總結下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