天天看點

在python中單線程,多線程,多程序對CPU的使用率實測以及GIL原理分析                                                                   -------  知識無價,汗水有情,如需搬運請注明出處,謝謝!

首先關于在python中單線程,多線程,多程序對cpu的使用率實測如下:

單線程,多線程,多程序測試代碼使用死循環。

1)單線程:

在python中單線程,多線程,多程式對CPU的使用率實測以及GIL原理分析                                                                   -------  知識無價,汗水有情,如需搬運請注明出處,謝謝!
在python中單線程,多線程,多程式對CPU的使用率實測以及GIL原理分析                                                                   -------  知識無價,汗水有情,如需搬運請注明出處,謝謝!

2)多線程:

在python中單線程,多線程,多程式對CPU的使用率實測以及GIL原理分析                                                                   -------  知識無價,汗水有情,如需搬運請注明出處,謝謝!
在python中單線程,多線程,多程式對CPU的使用率實測以及GIL原理分析                                                                   -------  知識無價,汗水有情,如需搬運請注明出處,謝謝!

3)多程序:

在python中單線程,多線程,多程式對CPU的使用率實測以及GIL原理分析                                                                   -------  知識無價,汗水有情,如需搬運請注明出處,謝謝!
在python中單線程,多線程,多程式對CPU的使用率實測以及GIL原理分析                                                                   -------  知識無價,汗水有情,如需搬運請注明出處,謝謝!

檢視cpu使用效率:

在python中單線程,多線程,多程式對CPU的使用率實測以及GIL原理分析                                                                   -------  知識無價,汗水有情,如需搬運請注明出處,謝謝!
在python中單線程,多線程,多程式對CPU的使用率實測以及GIL原理分析                                                                   -------  知識無價,汗水有情,如需搬運請注明出處,謝謝!

開始觀察分别執行時候cpu的使用效率:

1)單線程執行的時候:

在python中單線程,多線程,多程式對CPU的使用率實測以及GIL原理分析                                                                   -------  知識無價,汗水有情,如需搬運請注明出處,謝謝!

2)多線程執行的時候:

在python中單線程,多線程,多程式對CPU的使用率實測以及GIL原理分析                                                                   -------  知識無價,汗水有情,如需搬運請注明出處,謝謝!

3)多程序執行的時候:

在python中單線程,多線程,多程式對CPU的使用率實測以及GIL原理分析                                                                   -------  知識無價,汗水有情,如需搬運請注明出處,謝謝!

總結:

1)單程序單線程時,對于雙核CPU的使用率隻能利用一個核,沒有充分利用兩個核。

2)單程序多線程時,對于雙核CPU的來說,雖然兩個核都用到的,不過很明顯沒有充分利用兩個核,這裡要說一個GIL(全局解釋器鎖)的概念:

GIL不同于線程之間的互斥鎖,GIL并不是Python的特性,而是Cpython引入的一個概念。(Jpython,PYPY)

Python的代碼由Python的解釋器執行(CPython)。那麼我們的代碼什麼時候被python解釋器執行,由我們的GIL也就是全局解釋器鎖進行控制。

當我們有一個線程開始通路解釋器的時候,GIL會将這把鎖上鎖,也就是說,其他線程無法再通路解釋器,也就意味着,其他的線程無法再被執行。

GIL執行流程:

  1. 加鎖GIL。

  2. 切換到一個線程去執行。

  3. 運作。

  4. 解鎖GIL。

再次重複以上步驟。

對于下列代碼GIL的執行流程:

import threading
import time
# 寫兩個函數,分别讓兩個線程去執行
# 這個兩個函數,都要通路我的全局變量
number = 0

def test1(count):
    global number
    for i in range(count):
        number += 1
    print(number)

def test2(count):
    global number
    for i in range(count):
        number += 1
    print(number)


def main():
    th1 = threading.Thread(target=test1,args= (1000000,))
    th2 = threading.Thread(target=test2, args=(1000000,))
    th1.start()
    th2.start()

    time.sleep(5)
    print(number)

if __name__ == '__main__':
    main()
      

運作結果(這裡充分的說明了多線程資源搶占問題):

在python中單線程,多線程,多程式對CPU的使用率實測以及GIL原理分析                                                                   -------  知識無價,汗水有情,如需搬運請注明出處,謝謝!

流程圖如下:

在python中單線程,多線程,多程式對CPU的使用率實測以及GIL原理分析                                                                   -------  知識無價,汗水有情,如需搬運請注明出處,謝謝!

線程1在執行到對全局變量加一操作的時候全局解釋器鎖被收回,線程2申請并得到了全局解釋器鎖開始運作,線上程2執行完加一操作以後對全局變量進行了修改并釋放了全局解釋器鎖。

這時線程1再次得到了全局解釋器鎖,從上次釋放全局解釋器鎖的地方開始繼續執行對全局變量加一的操作,記住,這裡線程1中的全局變量還是開始的0,雖然線程2已經對其進行了加一的操作,但是線程1并不知道,線程1還是會接着上一次的位置開始執行,是以線程1在執行完加一操作的時候同樣把1再次指派給了全局變量num,也就是說,線程2執行完加一操作之後指派過去的1又被線程1指派過去的1所覆寫,加了兩次等于加了一次!類似于協程,隻是做了一個執行代碼來回切換的操作!

是以在Python中,同一時刻,隻能有一個線程被執行。是以Python中的多線程是假的。

既然這樣我們為什麼還要用多線程呢?

其實多線程也有它的好處,例如我們在進行IO操作的時候,有效的組織了程式的阻塞,不至于一直無限的等待。

3)多程序時,對于雙核CPU來說,每個程序的優先級都是同等的,所配置設定的資源也是相等的,兩個程序的時候完全可以充分的利用雙核CPU,而且由于計算密集型的任務完全是依靠于cpu的核數,是以需要盡量的完全利用cpu,這時候多程序的好處就能夠完美的展現出來。

                                                                   -------  知識無價,汗水有情,如需搬運請注明出處,謝謝!