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

歡迎訪問 生活随笔!

生活随笔

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

python

python全局解释锁_Python GIL 全局解释性锁介绍

發布時間:2025/4/16 python 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python全局解释锁_Python GIL 全局解释性锁介绍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是GIL

GIL (Global Interpreter Lock),全局解釋性鎖,它上鎖的對象是解釋器,而Python代碼的運行需要解釋器進行解釋成字節碼并提供虛擬機運行,這么大粒度的鎖意味著,一個Python進程內的線程只有先獲得GIL,才能得到代碼執行的機會,這個鎖使得Python進程的多線程無法利用多核cpu帶來性能提升。

但需要明確的一點是,GIL并不是Python的特性,而是CPython(最常用的Python解釋器)的特性。這意味著我們可以使用其他的Python解釋器從而繞過GIL的困擾,如JPython就沒有GIL。但由于CPython是大部分環境下默認的Python解釋器,而且Python社區大部分第三方庫也依賴GIL這個特性提供的線程安全,由于這樣的歷史路徑依賴,我們對GIL是欲罷不能。

看見GIL

接下來我們通過幾個簡單的例子來看看GIL對多核利用的影響

運行如下代碼看看CPU的占用率

123456

def dead_loop():

while True:

pass

if __name__ == "__main__":

dead_loop()

測試的機器是個人 macbook pro,4個物理CPU,劃分為8個邏輯CPU;可以看到該程序的確是把單核的占用跑滿了;接著我們多開一個線程一起跑dead_loop,線程是CPU調度的基本單位,按道理兩個線程應該并行運行,CPU占用應該提高一倍;

12345678910111213

import threading

def dead_loop():

while True:

pass

if __name__ == "__main__":

t = threading.Thread(target=dead_loop)

t.start()

dead_loop()

t.join()

如圖,確實是運行了兩個線程,但是只有一個線程是激活的,只跑滿一個核,CPU的占用率依舊是 1?8 左右 【因為有其他用戶程序,因此略高于 1?8 】。

作為對比,我們使用Golang跑兩個線程看看。

123456789101112131415

package main

func main(){

ch := make(chan int, 0)

k := 1

for i:=0; i<2; i++{

go func() {

for ; k>0 ; {

}

}()

}

}

可以看到,Golang的確按照預期的那樣,兩個線程在死循環運行,CPU占用率達到總的 1?4 左右。

從以上的示例我們可以發現,GIL確實限制了Python進程的多線程對多核CPU的利用。

怎么辦

使用其他解釋器

GIL只是CPython的產物,像JPython和IronPython這樣的解釋器由于實現語言的特性,它們不需要GIL的幫助,但是由于用來Java/C#用于解釋器的實現,它們也失去了利用社區眾多C語言模塊有用特性的機會。【Done is better than perfect】

用multiprocessing替代Thread

multiprocessing庫的出現很大程度上是為了彌補thread庫因為GIL而低效的缺陷,它使用了多進程而不是多線程,而每個進程有自己獨立的GIL,因此不會出現進程間的GIL爭搶。

但是multiprocessing也有其他麻煩,比如本來的多線程的同步和通信機制在多進程下就用不了了,拿計數器來舉例子,如果要多個線程同時累加一個變量,對于thread來說,聲明一個global變量,加個訪問鎖即可搞定;但是由于進程有自己獨立的地址空間,無法直接訪問彼此的變量數據,因此這個共享數據就必須從進程里提出到更高層的存儲中,苦呀。

看看多進程的CPU占用

12345678910111213

import multiprocessing

def dead_loop():

while True:

pass

if __name__ == "__main__":

p = multiprocessing.Process(target=dead_loop)

p.start()

dead_loop()

p.join()

開了兩個進程,俱跑滿了單核

社區的努力

Python社區也一直在努力地改進GIL,甚至嘗試去除GIL

將切換粒度從基于opcode計數改成基于時間片計數

避免最近一次釋放GIL鎖的線程再次被立即調度

新增線程優先級功能(高優先級可以迫使其他線程釋放所持有的GIL鎖)

總結

Python GIL是功能與性能之間權衡后的產物,雖然它的存在導致Python單進程的CPU密集型多線程形同虛設,但它有其存在的合理性【簡單有用地實現線程安全】,也有其較難改變的客觀因素【歷史路徑依賴】。

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的python全局解释锁_Python GIL 全局解释性锁介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。