1. 程式人生 > >python多線程的一些名詞的解釋

python多線程的一些名詞的解釋

img 主線程 函數 這一 應用 重入 作用 支持 無法

相對於多進程,多線程的開銷是很小的。

多線程有如下的特性:

1.在主進程下開啟多個線程,每個線程都跟主進程的pid一樣

2.同一進程內開啟的多個線程是共享該進程地址空間的

3.守護線程會等待主線程運行完畢後被銷毀

3.1、對主進程來說,運行完畢指的是主進程代碼運行完畢。

主進程在其代碼結束後就已經算運行完畢了(守護進程在此時就被回收),然後主進程會一直等非守護的子進程都運行完畢後回收子進程的資源(否則會產生僵屍進程),才會結束,

3.2、對主線程來說,運行完畢指的是主線程所在的進程內所有非守護線程統統運行完畢,主線程才算運行完畢

主線程在其他非守護線程運行完畢後才算運行完畢(守護線程在此時就被回收)。因為主線程的結束意味著進程的結束,進程整體的資源都將被回收,而進程必須保證非守護線程都運行完畢後才能結束。

GIL全局解釋鎖

GIL本質就是一把互斥鎖,既然是互斥鎖,所有互斥鎖的本質都一樣,都是將並發運行變成串行,以此來控制同一時間內共享數據只能被一個任務所修改,進而保證數據安全。

1.每次執行python程序,都會產生一個獨立的進程。例如python test.pypython aaa.pypython bbb.py會產生3個不同的python進程。
2.
在一個python的進程內,不僅有test.py的主線程或者由該主線程開啟的其他線程,還有解釋器開啟的垃圾回收等解釋器級別的線程,總之,所有線程都運行在這一個進程內,毫無疑問

2.1所有數據都是共享的,這其中,代碼作為一種數據也是被所有線程共享的(

test.py的所有代碼以及Cpython解釋器的所有代碼)例如:test.py定義一個函數work(代碼內容如下圖),在進程內所有線程都能訪問到work的代碼,於是我們可以開啟三個線程然後target都指向該代碼,能訪問到意味著就是可以執行。

2.2所有線程的任務,都需要將任務的代碼當做參數傳給解釋器的代碼去執行,即所有的線程要想運行自己的任務,首先需要解決的是能夠訪問到解釋器的代碼。

Lock

鎖的目的是為了保護共享的數據,同一時間只能有一個線程來修改共享的數據

保護不同的數據就應該加不同的鎖。

GIL Lock是兩把鎖,保護的數據不一樣,前者是解釋器級別的(當然保護的就是解釋器級別的數據,比如垃圾回收的數據),後者是保護用戶自己開發的應用程序的數據,很明顯

GIL不負責這件事,只能用戶自定義加鎖處理,即Lock。流程大概如下圖:

技術分享圖片

GIL與多線程

有了GIL的存在,同一時刻同一進程中只有一個線程被執行

對於大的cpu處理任務一般分為2種:

計算密集型I/O密集型

在python中,對於目前的多核計算機來說,結論:

如果並發的多個任務是計算密集型:多進程效率高,如金融分析

如果並發的多個任務是I/O密集型:多線程效率高,如socket,爬蟲,web

死鎖現象

所謂死鎖: 是指兩個或兩個以上的進程或線程在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些內部永遠在互相等待的進程稱為死鎖進程。

RLock

解決方法,遞歸鎖,在Python中為了支持在同一線程中多次請求同一資源,python提供了可重入鎖RLock

python多線程的一些名詞的解釋