1. 程式人生 > >python GIL全域性直譯器鎖的理解

python GIL全域性直譯器鎖的理解

GIL的全稱是:Global Interpreter Lock,意思就是全域性直譯器鎖,這個GIL並不是python的特性,他是隻在Cpython直譯器裡引入的一個概念,而在其他的語言編寫的直譯器裡就沒有這個GIL例如:Jython,Pypy

為什麼會有gil?:

       隨著電腦多核cpu的出現核cpu頻率的提升,為了充分利用多核處理器,進行多執行緒的程式設計方式更為普及,隨之而來的困難是執行緒之間資料的一致性和狀態同步,而python也利用了多核,所以也逃不開這個困難,為了解決這個資料不能同步的問題,設計了gil全域性直譯器鎖。

說到gil直譯器鎖,我們容易想到在多執行緒中共享全域性變數的時候會有執行緒對全域性變數進行的資源競爭,會對全域性變數的修改產生不是我們想要的結果,而那個時候我們用到的是python中執行緒模組裡面的互斥鎖,哪樣的話每次對全域性變數進行操作的時候,只有一個執行緒能夠拿到這個全域性變數;看下面的程式碼:

import threading
global_num = 0
def test1():
    global global_num
    for i in range(1000000):
        global_num += 1
print("test1", global_num)


def test2():
    global global_num
    for i in range(1000000):
        global_num += 1
print("test2", global_num)

t1 = threading.Thread(target=test1)
t2 = threading.Thread(target
=test2) t1.start() t2.start()

在上面的例子裡,我們建立了兩個執行緒來爭奪對global_num的加一操作,但是結果並非我們想要的,所以我們在這裡加入了互斥鎖

import threading
import time
global_num = 0
lock = threading.Lock()

def test1():
    global global_num
    lock.acquire()
    for i in range(1000000):
        global_num += 1
lock.release()
    print("test1", global_num)


def 
test2(): global global_num lock.acquire() for i in range(1000000): global_num += 1 lock.release() print("test2", global_num) t1 = threading.Thread(target=test1) t2 = threading.Thread(target=test2) start_time = time.time() t1.start() t2.start()

這回能得到我們想要的結果,在之前我的博文裡也說到過這個問題,在這裡就不多累贅了。

而在Cpython直譯器中,當我們的python程式碼有一個執行緒開始訪問直譯器的時候,GIL會把這個大鎖給鎖上,此時此刻其他的執行緒只能乾等著,無法對直譯器的資源進行訪問,這一點就跟我們的互斥鎖相似。而只是這個過程發生在我們的Cpython中,同時也需要等這個執行緒分配的時間到了,這個執行緒把gil釋放掉,類似我們互斥鎖的lock.release()一樣,另外的執行緒才開始跑起來,說白了,這無疑也是一個單執行緒。

看如下的圖,也只是把我第一段程式碼的變數變成count,因為這裡我們忽略掉互斥鎖,只考慮gil


執行過程:1.thread1拿到全域性變數count 

               2.thread1申請到python直譯器的gil

               3.直譯器呼叫系統原生執行緒

               4.在cpu1上執行規定的時間

               5.執行時間到了,要求釋放[email protected]等下一次得到gil的時候,程式從這裡接著這一次開始執行

               6.thread2拿到了全域性變數,此時thread1對全域性count的操作並未完成,所以thread拿到的和thread拿到的count其實是相同的,這樣也很好解釋為什麼結果不是200萬 而是少於200萬

               7.thread2申請到了gil鎖

               8.呼叫原生的執行緒

               9.如果是單核cpu則會在cup1上執行,(不是重點),如圖在cpu3上執行

               10.執行規定的時間,此時完成了對count的加一操作

               11.執行時間還未到,執行緒2執行完對count操作,並給count加一,並且釋放了gil鎖

               12.執行緒1又申請到了gil鎖,重複之前的操作。

               13.執行緒1執行萬對count的操作,執行時間到,釋放gil鎖

綜合上面的步驟就能很好的理解gil鎖

哪些情況適合用多執行緒呢:

    只要在進行耗時的IO操作的時候,能釋放GIL,所以只要在IO密集型的程式碼裡,用多執行緒就很合適

哪些情況適合用多程序呢:

    用於計算密集型,比如計算某一個資料夾的大小。


相關推薦

python GIL全域性直譯器理解

GIL的全稱是:Global Interpreter Lock,意思就是全域性直譯器鎖,這個GIL並不是python的特性,他是隻在Cpython直譯器裡引入的一個概念,而在其他的語言編寫的直譯器裡就沒有這個GIL例如:Jython,Pypy為什麼會有gil?:       

關於pythonGIL全域性直譯器的簡單理解

GIL是直譯器內部的一把鎖,確切一點說是CPython直譯器內部的一把鎖,所以要注意區分 這和我們在Python程式碼中使用執行緒鎖Lock並不是一個層面的概念。 1. GIL產生的背景: 在CPython解釋內部執行多個執行緒的時候,每個執行緒都需要直譯器內部申請相應

python多執行緒和GIL全域性直譯器

1、執行緒     執行緒被稱為輕量級程序,是最小執行單元,系統排程的單位。執行緒切換需要的資源一般,效率一般。  2、多執行緒         在單個程式中同時執行多個執行緒完成不同的工作,稱為多執行緒 3、

GIL全域性直譯器

併發:進行交替處理多件事情。 並行:多個cpu同時處理多個事,只在多核上能實現。  GIL是全域性解析器鎖,保證同一時刻只有一個執行緒可以使用cpu,讓我們的多執行緒沒辦法真正實現並行。 在一個程序中只有一個GIL鎖,那個執行緒拿到GIL就可以使用cpu 多個程序有多

GIL(全域性直譯器)

1. 單執行緒死迴圈在VMware虛擬軟體中將Ubuntu設定為單核cpu# 主執行緒死迴圈,佔滿cpu while True: pass 2. 多執行緒死迴圈在VMware虛擬軟體中將Ubuntu設定為雙核cpuimport threading #子執行緒死迴圈

網路程式設計之多執行緒——GIL全域性直譯器

網路程式設計之多執行緒——GIL全域性直譯器鎖 一、引子 定義: In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python b

python 全域性直譯器(GIL)的問題

GIL即全域性直譯器鎖,是屬於直譯器層面的互斥鎖,確切的說是CPython直譯器內部的一把鎖。GIL是為了鎖定整個直譯器內部的全域性資源,每個執行緒想要執行首先獲取GIL,而GIL本身又是一把互斥鎖,造成所有執行緒只能一個一個併發交替的執行。 GIL產生的背景 在CPyt

Python 多執行緒 多程序 全域性直譯器GIL join

Python 程式碼的執行由Python 虛擬機器(也叫直譯器主迴圈)來控制。Python 在設計之初就考慮到要在主迴圈中,同時只有一個執行緒在執行,就像單CPU 的系統中執行多個程序那樣,記憶體中可以存放多個程式,但任意時刻,只有一個程式在CPU 中執行。同樣地,雖然Py

Python 執行速度慢原因之一一GIL全域性直譯器)視覺化

因為它是GIL(全域性直譯器鎖) 現代計算機的 CPU 有多個核心,有時甚至有多個處理器。為了利用所有計算能力,作業系統定義了一個底層結構,叫做執行緒,而一個程序(例如 Chrome瀏覽器)能夠生成多個執行緒,通過執行緒來執行系統指令。這樣如果一個程序是要使用很多 CPU,

python高階程式設計上— GIL全域性直譯器和深淺拷貝

①GIL:全域性直譯器鎖 1):python直譯器分為兩種,一種是C-pytohn ,另一種是JAVA-python 2):python語言和GIL沒有關係。GIL的造成是由於使用C-python直譯器造成的。由於90年代電腦沒有並行的多核電腦,因此C-python直譯器沒有考慮多執行緒的問

全域性直譯器GIL

解釋一下對GIL的理解?   GIL 又叫全域性直譯器鎖,首先說一點,Python語言與GIL全域性直譯器鎖沒有關係,僅僅是因為歷史原因,在cpython直譯器中還存在GIL難以移除。GIL是功能與效能權衡後的產物,它有著存在的合理性,也有著難以移除的歷史客觀因素。   為什麼存在GIL?

python3.5全域性直譯器GIL-實現原理淺析

python3全域性直譯器鎖淺談 本文環境python3.5.2。 python全域性直譯器鎖 In CPython, the global interpreter lock, or GIL, is a mutex that prevents mul

Python---全域性直譯器

全域性直譯器鎖(Global Interpreter Lock ): 在 Python 語言的主流實現 CPython 中,GIL 是一個貨真價實的全域性執行緒鎖,在直譯器解釋執行任何 Python 程式碼時,都需要先獲得這把鎖才行,在遇到 I/O 操作時會釋放這把鎖。如果是

什麼是python全域性解釋GIL)?

      我們所說的Python全域性解釋鎖(GIL)簡單來說就是一個互斥體(或者說鎖),這樣的機制只允許一個執行緒來控制Python直譯器。      這就意味著在任何一個時間點只有一個執行緒處於執行狀態。GIL對執行單執行緒任務的程式設計師們來說並沒什麼顯著影響,但是它成為了計算密集型(CPU-boun

python gil解釋器 IO阻塞線程 系統調用

img blog 線程 python mage nbsp 技術 log images 融匯貫通了 哇哈哈哈 關於釋放和獲取說明,說的好啊 python gil解釋器鎖 IO阻塞線程 系統調用

python-GIL、死遞歸及線程補充

self. for 提升 數字 test with edi 數據 thread 一、GIL介紹 GIL全稱 Global Interpreter Lock ,中文解釋為全局解釋器鎖。它並不是Python的特性,而是在實現python的主流Cpython解釋器時所引入的一個

python3多執行緒和GIL全域性直譯器

GIL的全稱是:Global Interpreter Lock,意思就是全域性直譯器鎖,這個GIL並不是python的特性,他是隻在Cpython直譯器裡引入的一個概念,而在其他的語言編寫的直譯器裡就沒有這個GIL例如:Jython,Pypy 為什麼會有gil?:      

GIL-全域性解釋

GIL全域性解釋鎖 在python中,存在一個GIL全域性解釋鎖,這個鎖並不是python特有的,而是cpython所有的,cpython是python的c語言寫的直譯器,使用jpython就不會出現GIL的問題 如果使用的多程序,程序與執行緒不同,程序與程序的記憶體空間是相互獨立的

關於python的執行緒和GIL全域性的一些見解

GIL全域性鎖是:Python語言和GIL沒有半毛錢關係。僅僅是由於歷史原因在Cpython虛擬機器(直譯器),難以移除GIL.每個執行緒在執行的過程都需要先獲取GIL,保證同一時刻只有一個執行緒可以執行程式碼。作用就是保證同一時刻只有一個執行緒可以執行程式碼,造成了我們使用多執行緒的時候無法實

GIL物件(全域性直譯器)[面試題]

GIL鎖物件(全域性直譯器)[面試題] 描述Python 中GIL的概念, 以及它對python多執行緒的影響?編寫一個多執行緒抓取網頁的程式,並闡述多執行緒抓取程式是否比單執行緒單執行緒效能有提升,並解釋原因。 #1.多執行緒 #子執行緒死迴圈 import threadi