python多執行緒鎖實戰 Python多執行緒鎖

2021-10-19 21:04:24 字數 1606 閱讀 6541

在多執行緒程式執行過程中,為什麼需要給一些執行緒加鎖以及如何加鎖,下面就來說一說。

1.給執行緒加鎖的原因

我們知道,不同程序之間的記憶體空間資料是不能夠共享的,試想一下,如果可以隨意共享,談何安全?但是乙個程序中的多個執行緒是可以共享這個程序的記憶體空間中的資料的,比如多個執行緒可以同時呼叫某一記憶體空間中的某些資料(只是呼叫,沒有做修改)。

試想一下,在某一程序中,記憶體空間中存有乙個變數物件的值為num=8,假如某一時刻有多個執行緒需要同時使用這個物件,出於這些執行緒要實現不同功能的需要,執行緒a需要將num減1後再使用,執行緒b需要將num加1後再使用,而執行緒c則是需要使用num原來的值8。由於這三個執行緒都是共享儲存num值的記憶體空間的,並且這三個執行緒是可以同時併發執行的,當三個執行緒同時對num操作時,因為num只有乙個,所以肯定會存在不同的操作順序,想象一下下面這樣操作過程:

因為num只有乙個,而三個操作都針對乙個num進行,所以上面的操作過程是完全有可能的,而原來執行緒a、b、c想要使用的num值應該分別為:7、9、8,這裡卻變成了:8、8、7。試想一下,如果這三個執行緒的操作對整個程式的執行是至關重要的,會造成什麼樣的後果?

因此出於程式穩定執行的考慮,對於執行緒需要呼叫記憶體中的共享資料時,我們就需要為執行緒加鎖。

2.python多執行緒鎖

(1)先看下面乙個未給執行緒加鎖的程式**:

程式執行結果如下:

上面是多個執行緒同時搶占同一記憶體空間的例子,但從執行結果中可以看到,程式依然順序地輸出1-19,而沒有出現上面說的情況,那是僅僅是因為量少的原因,雖然執行正常,沒有出錯,但是並不代表不會出錯。

(2)看下面給執行緒加鎖的**:

程式執行結果如下:

程式的執行結果肯定是會正常的,而在沒有給執行緒加鎖之前,則有可能是正常,注意這是兩種完全不同的概念。

分析一下上面的程式:在某一線程修改num的值時,即給該執行緒加鎖,該執行緒加鎖後,只要是該執行緒需要呼叫的**以及涉及的記憶體空間,都會立即被鎖上,比如這裡的"number+=1",其它執行緒雖然也在併發同時執行,但是不能執行"number+=1"這行**的,即不能夠去訪問或修改num這乙個共享記憶體空間的資料,只能等待該執行緒解鎖後才能執行;當該執行緒解鎖後,另乙個執行緒馬上加鎖再來修改number的值,同時也不允許其它執行緒占用,如此類推,直到所有執行緒執行完畢。

根據上面的分析,為執行緒加鎖就可以解決前面講的執行緒安全問題。

(3)為了更好的理解執行緒加鎖的乙個過程,把上面的**修改為如下:

執行結果如下:

由執行時間可以更好的說明上面的執行過程,但為什麼會這樣呢?下面來分析一下:由(2)的分析可知,雖然20個執行緒都是在同時併發執行run這乙個函式,這裡與(2)不同在於,(2)只加鎖了涉及修改number的程式**,而這裡是加鎖了整乙個函式!所以在20個執行緒同時開始併發執行這個函式時,由於每乙個執行緒的執行都要加鎖,並且加鎖的是整乙個執行的函式,因此其它執行緒就無法呼叫該函式中的程式**,只能等待乙個執行緒執行完畢後再呼叫該函式的程式**,如此一來,乙個執行緒的執行需要sleep(1)一次,則20個執行緒的執行就需要sleep(1)20次,並且該過程是序列的,因此我們才看到如上面所說的程式執行過程,也可以清晰的知道為什麼程式的執行需要20s了。

由上面的分析,我們不僅可以知道為什麼要給執行緒加鎖以及如何加鎖,還可以比較清楚的知道執行緒加鎖的乙個過程了,以後在編寫程式的時候,類似情況的,我們就應該要為執行緒加鎖。

python 多執行緒 鎖

參考 python cookbook 12章 啟動和停止執行緒 start 啟動執行緒 is alive 判斷是否已經結束 join 請求連線某個執行緒,等待該執行緒結束,才退出join函式 daemon引數,守護執行緒,該執行緒無法被連線,主線程結束後自動銷毀。2.7不適用 終止執行緒 需要自己構...

python多執行緒鎖 python的多執行緒程式設計之鎖

1 背景概述 在python中,要保證資料的正確性,並且自己對資料進行控制,對資料進行加鎖並且自己釋放鎖。多執行緒的主要目的為了提高效能與速度,用在無關的方向是最好的,例如在使用爬蟲的時候,可以使用多執行緒來進行爬取資料,因為在這些執行緒之間沒有需要共同操作的資料,從而在這個時候利用是最好的。如果需...

python執行緒互斥鎖 Python多執行緒與互斥鎖

多執行緒 threading python的thread模組是 較底層的模組,python的threading 模組是對thread做了 些包裝的,可以更加 便的被使 1.使 threading模組 from threading import thread 匯入模組 t thread target ...