你自己想想看這個情景
執行緒AB同時操作list
list的[0]初始值為0
執行緒A 操作100次
list[0]+=1
執行緒B 操作100次
線上程A 對於 list[0]進行操作時
list[0]為0, 還沒等執行緒A完成加一操作, 就被切換到執行緒B了
線上程B 眼裡,
list[0]還是為0, 於是執行加一操作.
再切換回執行緒A, 繼續未完成的加一操作
你發現了沒!!! 執行緒AB各對list[0]進行了加一,預期結果是2 但結果還是1
Python的list不是完全執行緒安全的.
所以加個執行緒鎖就完了.
話說為什麼, 有了執行緒鎖還需要GIL呢?
因為, 有了GIL, 提供併發就變得很容易. 直譯器只要計算每個執行緒的執行時間就好了
時間一到, 將這個執行緒凍結, 記憶體管理很簡單.
等等, 你還是沒解釋, 如果我已經給執行緒上了鎖, 為什麼還是要被GIL限制?
一向符合人類直覺的Python, 有個很反直覺的機制.
Py的變數a其實不是C系編譯語言的變數.
Python維護著一個字典, 儲存著a和對應數值的指標.
用某黑Python的大牛的話說, Python企圖用字典裝下世界..
如果變成真多執行緒
對於這個字典的維護將會很複雜.
多個執行緒真正同時操作一個字典, Python引以為傲的字典效能, 估計就沒那麼強了.
就是說, Python字典的效能強大,是建立線上程不安全的基礎上.
而字典在Python中的位置又是如此重要, 一個緩慢的字典, 會嚴重拖慢Python的解釋速度.
多執行緒操作多個獨立字典. 那樣還是要同步.
那為什麼不採用多程序呢? 這就是社群主流的看法.
雖然理論上執行緒成本更低, 但是那樣程式碼就改成面目全非了..
你自己想想看這個情景
執行緒AB同時操作list
list的[0]初始值為0
執行緒A 操作100次
list[0]+=1
執行緒B 操作100次
list[0]+=1
線上程A 對於 list[0]進行操作時
list[0]為0, 還沒等執行緒A完成加一操作, 就被切換到執行緒B了
線上程B 眼裡,
list[0]還是為0, 於是執行加一操作.
再切換回執行緒A, 繼續未完成的加一操作
你發現了沒!!! 執行緒AB各對list[0]進行了加一,預期結果是2 但結果還是1
Python的list不是完全執行緒安全的.
所以加個執行緒鎖就完了.
話說為什麼, 有了執行緒鎖還需要GIL呢?
因為, 有了GIL, 提供併發就變得很容易. 直譯器只要計算每個執行緒的執行時間就好了
時間一到, 將這個執行緒凍結, 記憶體管理很簡單.
等等, 你還是沒解釋, 如果我已經給執行緒上了鎖, 為什麼還是要被GIL限制?
一向符合人類直覺的Python, 有個很反直覺的機制.
Py的變數a其實不是C系編譯語言的變數.
Python維護著一個字典, 儲存著a和對應數值的指標.
用某黑Python的大牛的話說, Python企圖用字典裝下世界..
如果變成真多執行緒
對於這個字典的維護將會很複雜.
多個執行緒真正同時操作一個字典, Python引以為傲的字典效能, 估計就沒那麼強了.
就是說, Python字典的效能強大,是建立線上程不安全的基礎上.
而字典在Python中的位置又是如此重要, 一個緩慢的字典, 會嚴重拖慢Python的解釋速度.
多執行緒操作多個獨立字典. 那樣還是要同步.
那為什麼不採用多程序呢? 這就是社群主流的看法.
雖然理論上執行緒成本更低, 但是那樣程式碼就改成面目全非了..