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 ,這樣其他線程就可以運行。這意味著多個線程可以并發等待套接字連接,這是一件好事。在同樣的時間內它們可以做更多的工作。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
