3 回答

TA貢獻1825條經(jīng)驗 獲得超4個贊
通常,對于任何線程安全問題,您都需要使用鎖來保護內(nèi)部數(shù)據(jù)結構。這可以通過各種級別的粒度來完成。
您可以使用細粒度的鎖定,其中每個單獨的結構都有其自己的鎖定。
您可以使用粗粒度鎖定,其中一種鎖定可以保護所有內(nèi)容(GIL方法)。
每種方法各有利弊。細粒度的鎖定允許更大的并行度-兩個線程不共享任何資源時可以并行執(zhí)行。但是,這需要更大的管理開銷。對于每一行代碼,您可能需要獲取并釋放幾個鎖。
相反,粗粒度方法則相反。兩個線程不能同時運行,但是單個線程將運行得更快,因為它并沒有做太多記賬工作。最終,它歸結為單線程速度和并行性之間的折衷。
曾有幾次嘗試在python中刪除GIL,但是單線程計算機的額外開銷通常太大。實際上,即使在多處理器計算機上,由于鎖爭用,某些情況實際上也會變慢。
其他編譯為字節(jié)碼的語言是否采用類似的機制?
它是多種多樣的,可能不應該將它視為語言屬性,而應該將其視為實現(xiàn)屬性。例如,有些Python實現(xiàn)(例如Jython和IronPython)使用其底層VM的線程方法,而不是GIL方法。此外,Ruby的下一個版本似乎正朝著引入GIL 邁進。

TA貢獻1836條經(jīng)驗 獲得超4個贊
以下來自官方的Python / C API參考手冊:
Python解釋器不是完全線程安全的。為了支持多線程Python程序,當前線程必須擁有一個全局鎖,才能安全地訪問Python對象。如果沒有鎖,即使是最簡單的操作也可能在多線程程序中引起問題:例如,當兩個線程同時增加同一對象的引用計數(shù)時,引用計數(shù)最終只能增加一次而不是兩次。
因此,存在這樣的規(guī)則,即只有已獲得全局解釋器鎖的線程才可以在Python對象上操作或調用Python / C API函數(shù)。為了支持多線程Python程序,解釋器會定期釋放并重新獲取鎖-默認情況下,每100個字節(jié)碼指令(可以通過sys.setcheckinterval()進行更改)。鎖定也被釋放并重新獲得,這可能會阻止?jié)撛诘淖枞鸌 / O操作(如讀取或寫入文件),以便在請求I / O的線程正在等待I / O操作完成的同時運行其他線程。
我認為這很好地概括了這個問題。
添加回答
舉報