python **的執行由python虛擬機器來控制,虛擬機器訪問由gil控制,保證其同一時刻只有一條執行緒執行。
雖然python能執行多執行緒,但是因為gil所以同一時刻只有一條執行緒在python直譯器執行。
多執行緒下python虛擬機器按以下方式執行:
1. 設定gil
2. 切換到一條執行緒去執行
3. 執行:
a. 執行python2虛擬機器執行1000位元組指令 或者 執行python3虛擬機器執行時間15ms位元組
b. 執行緒主動讓出控制(遭遇sleep或者io操作也將觸發)
4. 把執行緒設定為睡眠狀態(等待狀態)
5. 釋放gil
6. 再次重複上述操作
執行緒何時切換?
(1)乙個執行緒無論何時開始睡眠或等待網路 i/o,其他執行緒總有機會獲取 gil 執行 python **。這是協同式多工處理。cpython 也還有搶占式多工處理。如果乙個執行緒不間斷地在 python 2 中執行 1000 位元組碼指令,或者不間斷地在 python 3 執行15 毫秒,那麼它便會放棄 gil,而其他執行緒可以執行。把這想象成有多個執行緒但只有乙個 cpu 時的時間片可用。
(2)當執行c/c++**時候,直到c函式執行完畢,才讓出gil。
讓我們回顧下 python 是如何執行的。你的程式分兩個階段執行。首先,python文字被編譯成乙個名為位元組碼的簡單二進位制格式。第二,python直譯器的主迴路,乙個名叫 pyeval_evalframeex() 的函式,流暢地讀取位元組碼,逐個執行其中的指令。
搶占式多工處理
當直譯器通過位元組碼時,它會定期放棄gil,而不需要經過正在執行**的執行緒允許,這樣其他執行緒便能執行:預設情況下,檢測間隔是1000 位元組碼。所有執行緒都執行相同的**,並以相同的方式定期從他們的鎖中抽出。在 python 3 gil 的實施更加複雜,檢測間隔不是乙個固定數目的位元組碼,而是15 毫秒。然而,對於你的**,這些差異並不顯著。
協同式多工處理
當一項任務比如網路 i/o啟動,而在長的或不確定的時間,沒有執行任何 python **的需要,乙個執行緒便會讓出gil,從而其他執行緒可以獲取 gil 而執行 python。
這種禮貌行為稱為協同式多工處理,它允許併發;多個執行緒同時等待不同事件。多個執行緒在同一時刻只能有乙個執行 python ,但一旦執行緒開始連線,它就會放棄 gil ,這樣其他執行緒就可以執行。這意味著多個執行緒可以併發等待套接字連線,這是一件好事。在同樣的時間內它們可以做更多的工作。
什麼時候使用多執行緒
使用多執行緒為什麼可以提高效率呢?io是關鍵。很多的應用要使用io,但是cpu是很快的,io往往是很慢的。看 main1.c include include include include include include char p void sys error int errnum void f...
在Ajax中什麼時候用GET什麼時候用POST?
當我們有大量資料要傳送時最好的辦法是一次發出多個只傳遞少量資訊的ajax呼叫時。如果你正用乙個ajax呼叫傳送大量資料,那麼最好是結束這種做法,因為這樣做並不能節約時間。因此,需要傳送大量資料能成為我們在get和post之間猶豫不決的理由嗎?這兩個方法都是為不同的目的而設計的,兩者的不同也在於其使用...
什麼時候用exists 什麼時候用in
in not in exists not exists 使用exists,oracle會首先檢查主查詢,然後執行子查詢直到它找到第乙個匹配項,這就節省了時間。oracle在執行in子查詢時,首先執行 子查詢,並將獲得的結果列表存放在乙個加了索引的臨時表中。在執行子查詢之前,系統先將主查詢掛起 待子查...