python 对象锁_也许你对 Python GIL 锁的理解是 错的。
我剛到現(xiàn)在這個公司時,聽到當時一個高級工程師(現(xiàn)已離職)大聲地跟他旁邊的同事說:
?Python 有 GIL 鎖,所以它的多線程實際上是單線程,所以寫多線程代碼不用考慮線程沖突,不用加鎖。
”相信現(xiàn)在看這篇文章的同學,不少人也是這樣認為的。
然而,我要告訴你的是,這句話前半句是對的,后半句是 錯的。Python 的多線程確實本質(zhì)上是單線程。但你依然需要考慮線程并發(fā)沖突。
我們來舉個例子:
場景 1:單線程
變量 a 的值為1.代碼讀取 a 的值,把它加 1 變成2.然后把2重新賦值給 a。代碼再次讀取 a 的值,把它加 1 變成3.然后重新把3復制給 a。最終 a 的值是3.
場景 2:偽多線程
Python 的多線程是偽多線程,意味著在微觀上它是單線程。同一個時間,只有一個線程在運行,其他線程是暫停的狀態(tài)?,F(xiàn)在有一個變量 a,它里面的值為1.
可以看到,即使同一時間只有一個線程在運行,但是兩個線程同時修改同一個變量時,也會發(fā)生并發(fā)沖突。
GIL 到底鎖的是什么?
大家都說 Python 有 GIL 鎖,那么這個鎖到底鎖的是什么東西??
GIL 的全稱是 Global Interpreter Lock, 全局解釋器鎖。它鎖的是解釋器而不是你的 Python 代碼。它防止多線程同時執(zhí)行 Python 的字節(jié)碼(bytecodes),防止多線程同時訪問 Python 的對象。
在 Python 官方文檔Releasing the GIL from extension code[1]中,有這樣一段話:
?Here is how these functions work: the global interpreter lock is used to protect the pointer to the current thread state. When releasing the lock and saving the thread state, the current thread state pointer must be retrieved before the lock is released (since another thread could immediately acquire the lock and store its own thread state in the global variable). Conversely, when acquiring the lock and restoring the thread state, the lock must be acquired before storing the thread state pointer.
”其中加黑的這一句話是說:GIL 鎖用來保護指向當前進程狀態(tài)的指針。
再看文檔Thread State and the Global Interpreter Lock[2]中提到的這樣一句話:
?Without the lock, even the simplest operations could cause problems in a multi-threaded program: for example, when two threads simultaneously increment the reference count of the same object, the reference count could end up being incremented only once instead of twice.
”當兩個線程同時提高同一個對象的引用計數(shù)時,(如果沒有 GIL 鎖)那么引用計數(shù)只會被提高了 1 次而不是 2 次。
大家注意我這兩段應用中的指針和引用計數(shù)。其中指針是 C 語言的概念,Python 沒有指針;引用計數(shù)是 Python 底層的概念。你平時寫的 Python 代碼,引用計數(shù)是在你調(diào)用變量的時候自動增加的,不需要你去手動加 1.
所以 GIL 鎖住的東西,都是不需要你的代碼直接交互的東西。
Python 的解釋器通過切換線程來模擬多線程并發(fā)的情況,如上面舉的例子,雖然同一個時間只有一個線程在活動,但仍然可以導致并發(fā)沖突。
所以,以后不要再說出 Python 不需要解決并發(fā)沖突這種話了。
參考資料
[1]Releasing the GIL from extension code: https://docs.python.org/3/c-api/init.html#releasing-the-gil-from-extension-code
[2]Thread State and the Global Interpreter Lock: https://docs.python.org/3/c-api/init.html#thread-state-and-the-global-interpreter-lock
總結(jié)
以上是生活随笔為你收集整理的python 对象锁_也许你对 Python GIL 锁的理解是 错的。的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Aview如何回放监控
- 下一篇: pythoni屏幕连点_【Flutter