并发编程中的GIL锁(全局解释器锁)自己理解的他为啥存在
自己的分析
GIL鎖就是一個全局解釋器鎖
也就是python中因為有垃圾回收機制的存在。垃圾回收機制也是一個線程,如果所有的線程都可以使用cpu的不同資源(也就是多核
cpu并行處理線程的情況)
-這里涉及到一個小知識
我們知道在一個語言中,要對一個變量名進行賦值操作,就不是表面所看見的拿到內存中所存儲的值,再拿到變量名,進行一個
等號的賦值操作,這樣的理解是錯誤的。他其實大致的原理是這樣子的:如下圖
也就是說我們再執行一個簡單的賦值操作的時候,會經過好幾道步驟,然后我們知道線程再運行的時候,可能會有多個線程同時運
行,這個時候cpu有個“反復橫跳”的機制,也就是好幾個線程之間跳來跳去,讓咱們的線程看起來像是并行(這里假設可以并行兩個,
但是另外一個線程過來了,所以才會可能中斷正在執行的線程,假設!!!),而且如果一個線程運行久了,cpu也就會中斷線程、
保護現場,之后運行其他的線程,這個時候可能會是在解釋器賦值的操作的時候,我們都知道線程間的數據是共享的,他們可能會
去修改同一個數據,而我們途中的 tmp = 10 就相當于獲取了需要修改的值,還沒有進行操作,cpu把我們中斷了,這個時候去運行
其他的線程,也去修改這個值,然后他們都獲取到的是同一個沒有經過修改的一樣的值,就會造成少修改一次的情況發生。造成數
據出錯,如果說我們的垃圾回收機制在此時生效,因為垃圾回收機制也是一個線程,他如果生效了,因為當時被中斷的線程沒有完
成賦值,所以那個值的引用技術為0,就會造成數據被垃圾回收機制回收,造成一個線程沒有值了,所以就有了全局解釋器鎖,讓
我們的線程是單個運行的,就不會造成數據被垃圾回收機制回收。
但是這樣也會造成我們的線程是沒有辦法實現多核cpu并行的操作的,他就只會是并發,如果要去實現并行也是可以的,就必須去開
進程,一個進程里面只有一個線程去運行,就可以實現并行但是站在的角度不同的話,因為cpu是一個運算的部件,所以說如果我們
的代碼是計算特別復雜的話,可以使用多進程并行的方式去執行,但是我們后端的操作中主要是io比計算多,所以使用多線程并發的
方式其實是比多進程要快的,因為創建線程的時間要遠遠小于創建進程的時間。
正規的分析
Python代碼的執行由Python虛擬機(也叫解釋器主循環)來控制。Python在設計之初就考慮到要在主循環中,同時只有一個線程在執行。雖然 Python 解釋器中可以“運行”多個線程,但在任意時刻只有一個線程在解釋器中運行。
對Python虛擬機的訪問由全局解釋器鎖(GIL)來控制,正是這個鎖能保證同一時刻只有一個線程在運行。
在多線程環境中,Python 虛擬機按以下方式執行:
設置 GIL;
切換到一個線程去運行;
運行指定數量的字節碼指令或者線程主動讓出控制(可以調用 time.sleep(0));
把線程設置為睡眠狀態;
解鎖 GIL;
再次重復以上所有步驟。
在調用外部代碼(如 C/C++擴展函數)的時候,GIL將會被鎖定,直到這個函數結束為止(由于在這期間沒有Python的字節碼被運行,所以不會做線程切換)編寫擴展的程序員可以主動解鎖GIL。
轉載于:https://www.cnblogs.com/xiongchao0823/p/11542606.html
總結
以上是生活随笔為你收集整理的并发编程中的GIL锁(全局解释器锁)自己理解的他为啥存在的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .dll与.lib的关系总结
- 下一篇: 递归锁,死锁,使用递归锁解决死锁,信号量