線程互斥鎖 Lock
- 前言
- Python 線程互斥鎖
-
- 1.建立互斥鎖
- 鎖定資源/解鎖資源
- Python 線程死鎖
-
- 1.引入庫
- 重點總結
前言
Python 線程互斥鎖
1.建立互斥鎖
# 導入線程threading子產品
import threading
# 建立互斥鎖
mutex = threading.Lock()
鎖定資源/解鎖資源
# 導入線程threading子產品
import threading
# 聲明全局變量
g_num = 0
# 建立互斥鎖
mutex = threading.Lock()
def my_thread1():
# 聲明全局變量
global g_num
# 循環 1000000 次,每次累計加 1
for i in range(0,1000000):
# 鎖定資源
mutex.acquire()
g_num = g_num + 1
# 解鎖資源
mutex.release()
def my_thread2():
# 聲明全局變量
global g_num
# 循環 1000000 次,每次累計加 1
for i in range(0,1000000):
# 鎖定資源
mutex.acquire()
g_num = g_num + 1
# 解鎖資源
mutex.release()
def main(i):
# 聲明全局變量
global g_num
# 初始化全局變量,初始值為 0
g_num = 0
# 建立兩個線程,對全局變量進行累計加 1
t1 = threading.Thread(target=my_thread1)
t2 = threading.Thread(target=my_thread2)
# 啟動線程
t1.start()
t2.start()
# 阻塞函數,等待線程結束
t1.join()
t2.join()
# 擷取全局變量的值
print("第%d次計算結果:%d "% (i,g_num))
if __name__ == "__main__":
# 循環4次,調用main函數,計算全局變量的值
for i in range(1,5):
main(i)
'''
輸出結果:
第1次計算結果:2000000
第2次計算結果:2000000
第3次計算結果:2000000
第4次計算結果:2000000
'''
注意:互斥鎖一旦鎖定之後要記得解鎖,否則資源會一直處于鎖定狀态;
Python 線程死鎖
1.引入庫
1.單個互斥鎖的死鎖:acquire / release 是成對出現的,互斥鎖對資源鎖定之後就一定要解鎖,否則資源會一直處于鎖定狀态,其他線程無法修改;任何一個線程沒有釋放資源 release,程式就會一直處于阻塞狀态(在等待資源被釋放)
2.多個互斥鎖的死鎖:在同時操作多個互斥鎖的時候一定要格外小心,因為一不小心就容易進入死循環。
# 導入線程threading子產品
import threading
# 導入線程time子產品
import time
# 建立互斥鎖
mutex_one = threading.Lock()
mutex_two = threading.Lock()
def programmer_thread1():
mutex_one.acquire()
print("我是程式員1,module1開發正式開始,誰也别動我的代碼")
time.sleep(2)
# 此時會堵塞,因為這個mutex_two已經被線程programmer_thread2搶先上鎖了,等待解鎖
mutex_two.acquire()
print("等待程式員2通知我合并代碼")
mutex_two.release()
mutex_one.release()
def programmer_thread2():
mutex_two.acquire()
print("我是程式員2,module2開發正式開始,誰也别動我的代碼")
time.sleep(2)
# 此時會堵塞,因為這個mutex_one已經被線程programmer_thread1搶先上鎖了,等待解鎖
mutex_one.acquire()
print("等待程式員1通知我合并代碼")
mutex_one.release()
mutex_two.release()
def main():
t1 = threading.Thread(target=programmer_thread1)
t2 = threading.Thread(target=programmer_thread2)
# 啟動線程
t1.start()
t2.start()
# 阻塞函數,等待線程結束
t1.join()
t2.join()
# 整合代碼結束
print("整合代碼結束 ")
if __name__ == "__main__":
main()
'''
輸出結果:
我是程式員1,module1開發正式開始,誰也别動我的代碼
我是程式員2,module2開發正式開始,誰也别動我的代碼
'''
分析:程式員 1 在等程式員 2 通知,程式員 2 在等程式員 1 通知,兩個線程都陷入阻塞中,因為兩個線程都在等待對方解鎖,這就是死鎖!是以在開發中對于死鎖的問題還是需要多多注意!
重點總結
1.線程與線程之間共享全局變量需要設定互斥鎖;
2.注意在互斥鎖操作中 acquire / release 成對出現,并且保證上鎖後一定要記得解鎖,避免造成死鎖;