日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python 对象锁_也许你对 Python GIL 锁的理解是 错的。

發(fā)布時間:2023/12/2 python 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 对象锁_也许你对 Python GIL 锁的理解是 错的。 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

攝影:產(chǎn)品經(jīng)理甜白與草莓更配~

我剛到現(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.

  • 線程 1 從 a 里面獲取到1,把它加1,線程 1 還沒有來得及把數(shù)字2重新賦值給變量 a 時,時間片切換到線程 2.
  • 此時線程 1 暫停。線程 2 去讀取變量 a,這個時候的 a 依然是1.線程 2 也把這個數(shù)字加1,變成2.
  • 時間片切換到線程 1,線程 2 暫停。線程 1 把數(shù)字2賦值給變量 a,此時 a 的值變成2.
  • 時間片切換到線程 2,線程 1 暫停。線程 2 把數(shù)字2賦值給變量 a,此時 a 的值還是2.
  • 可以看到,即使同一時間只有一個線程在運行,但是兩個線程同時修改同一個變量時,也會發(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)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。