Python GIL(Global Interpreter Lock)

來源:互聯網
上載者:User

標籤:GIL 解析器鎖

一、GIL介紹GIL本質就是一把互斥鎖,既然是互斥鎖,所有互斥鎖的本質都一樣,都是將並發運行變成串列,以此來控制同一時間內共用資料只能被一個任務所修改,進而保證資料安全。可以肯定的一點是:保護不同的資料的安全,就應該加不同的鎖。要瞭解GIL,首先確定一點:每次執行python程式,都會產生一個獨立的進程。例如python test.py,python aaa.py,python bbb.py會產生3個不同的python進程在一個python的進程內,不僅有test.py的主線程或者由該主線程開啟的其他線程,還有解譯器開啟的記憶體回收等解譯器層級的線程,總之,所有線程都運行在這一個進程內。1、所有資料都是共用的 其中代碼作為一種資料也是被所有線程共用的(test.py的所有代碼以及Cpython解譯器的所有代碼)2、所有線程的任務,都需要將任務的代碼當做參數傳給解譯器的代碼去執行,即所有的線程要想運行自己的任務,首先需要解決的是能夠訪問到解譯器的代碼 綜上: 如果多個線程的target=work,那麼執行流程是 多個線程先訪問到解譯器的代碼,即拿到執行許可權,然後將target的代碼交給解譯器的代碼去執行解譯器的代碼是所有線程共用的,所以記憶體回收線程也可能訪問到解譯器的代碼而去執行,這就導致了一個問題: 對於同一個資料100,可能線程1執行x=100的同時,而記憶體回收執行的是回收100的操作,解決這種問題沒有什麼高明的方法? 就是加鎖處理,如的GIL,保證python解譯器同一時間只能執行一個任務的代碼二、GIL與LockGIL保護的是解譯器級的資料,保護使用者自己的資料則需要自己加鎖處理,如


三、GIL與多線程有了GIL的存在,同一時刻同一進程中只有一個線程被執行進程可以利用多核,但是開銷大,而python的多線程開銷小,但卻無法利用多核優勢,要解決這個問題,我們需要在幾個點上達成一致:    1. cpu到底是用來做計算的,還是用來做I/O的?    2. 多cpu,意味著可以有多個核並行完成計算,所以多核提升的是計算效能    3. 每個cpu一旦遇到I/O阻塞,仍然需要等待,所以多核對I/O操作沒什麼用處 一個工人相當於cpu,此時計算相當於工人在幹活,I/O阻塞相當於為工人幹活提供所需原材料的過程,工人幹活的過程中如果沒有原材料了,則工人幹活的過程需要停止,直到等待原材料的到來。如果你的工廠乾的大多數任務都要有準備原材料的過程(I/O密集型),那麼你有再多的工人,意義也不大,還不如一個人,在等材料的過程中讓工人去幹別的活,反過來講,如果你的工廠原材料都齊全,那當然是工人越多,效率越高結論:    對計算來說,cpu越多越好,但是對於I/O來說,再多的cpu也沒用    當然對運行一個程式來說,隨著cpu的增多執行效率肯定會有所提高(不管提高幅度多大,總會有所提高),這是因為一個程式基本上不會是純計算或者純I/O,所以我們只能相對的去看一個程式到底是計算密集型還是I/O密集型,從而進一步分析python的多線程到底有無用武之地。假設一種情況:    現在有四個任務需要處理,處理方式是要有並發的效果,解決方案可以是:    方案一:開啟四個進程    方案二:一個進程下,開啟四個線程    單核情況下,分析結果:         如果四個任務是計算密集型,沒有多核來並行計算,方案一徒增了建立進程的開銷,方案二勝        如果四個任務是I/O密集型,方案一建立進程的開銷大,且進程的切換速度遠不如線程,方案二勝    多核情況下,分析結果:        如果四個任務是計算密集型,多核意味著並行計算,在python中一個進程中同一時刻只有一個線程執行用不上多核,方案一勝        如果四個任務是I/O密集型,再多的核也解決不了I/O問題,方案二勝結論:    現在的電腦基本上都是多核,python對於計算密集型的任務開多線程的效率並不能帶來多大效能上的提升,甚至不如串列(沒有大量切換)    但是,對於IO密集型的任務效率還是有顯著提升的。四、多線程效能測試1、計算密集型:多進程效率高    from multiprocessing import Process    from threading import Thread    import os,time    def work():            res=0            for i in range(100000000):                    res*=i    l=[]    print(os.cpu_count()) #本機為4核    start=time.time()    for i in range(4):            # p=Process(target=work) #耗時18s多            p=Thread(target=work) #耗時26s多            l.append(p)            p.start()    for p in l:            p.join()    stop=time.time()    print(‘run time is %s‘ %(stop-start))2、i/o密集型:多線程效率高    from multiprocessing import Process    from threading import Thread    import threading    import os,time    def work():            time.sleep(2)            print(‘===>‘)    l=[]    print(os.cpu_count()) #本機為4核    start=time.time()    for i in range(400):            p=Process(target=work) #耗時4s多,大部分時間耗費在建立進程上            # p=Thread(target=work) #耗時2s多            l.append(p)            p.start()    for p in l:            p.join()    stop=time.time()    print(‘run time is %s‘ %(stop-start))應用:多線程用於IO密集型,如socket,爬蟲,web多進程用於計算密集型,如金融分析

Python GIL(Global Interpreter Lock)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.