死鎖 與 遞迴鎖
阿新 • • 發佈:2018-11-09
程序也有死鎖與遞迴鎖,在程序那裡忘記說了,放到這裡一切說了額
所謂死鎖: 是指兩個或兩個以上的程序或執行緒在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的程序稱為死鎖程序,如下就是死鎖
1 from threading import Lock as Lock 2 import time 3 mutexA=Lock() 4 mutexA.acquire() 5 mutexA.acquire() 6 print(123) 7 mutexA.release() 8 mutexA.release()9 10 死鎖
解決方法,遞迴鎖,在Python中為了支援在同一執行緒中多次請求同一資源,python提供了可重入鎖RLock。
這個RLock內部維護著一個Lock和一個counter變數,counter記錄了acquire的次數,從而使得資源可以被多次require。直到一個執行緒所有的acquire都被release,其他的執行緒才能獲得資源。上面的例子如果使用RLock代替Lock,則不會發生死鎖:
from threading import RLock as Lock import time mutexA=Lock() mutexA.acquire() mutexA.acquire()print(123) mutexA.release() mutexA.release() 遞迴鎖RLock
典型問題: 科學家吃麵
1 import time 2 from threading import Thread,Lock 3 noodle_lock = Lock() 4 fork_lock = Lock() 5 def eat1(name): 6 noodle_lock.acquire() 7 print('%s 搶到了麵條'%name) 8 fork_lock.acquire() 9 print('%s 搶到了叉子'%name) 10 print('%s 吃麵'%name) 11 fork_lock.release() 12 noodle_lock.release() 13 14 def eat2(name): 15 fork_lock.acquire() 16 print('%s 搶到了叉子' % name) 17 time.sleep(1) 18 noodle_lock.acquire() 19 print('%s 搶到了麵條' % name) 20 print('%s 吃麵' % name) 21 noodle_lock.release() 22 fork_lock.release() 23 24 for name in ['哪吒','egon','yuan']: 25 t1 = Thread(target=eat1,args=(name,)) 26 t2 = Thread(target=eat2,args=(name,)) 27 t1.start() 28 t2.start() 29 30 死鎖問題
1 import time 2 from threading import Thread,RLock 3 fork_lock = noodle_lock = RLock() 4 def eat1(name): 5 noodle_lock.acquire() 6 print('%s 搶到了麵條'%name) 7 fork_lock.acquire() 8 print('%s 搶到了叉子'%name) 9 print('%s 吃麵'%name) 10 fork_lock.release() 11 noodle_lock.release() 12 13 def eat2(name): 14 fork_lock.acquire() 15 print('%s 搶到了叉子' % name) 16 time.sleep(1) 17 noodle_lock.acquire() 18 print('%s 搶到了麵條' % name) 19 print('%s 吃麵' % name) 20 noodle_lock.release() 21 fork_lock.release() 22 23 for name in ['哪吒','egon','yuan']: 24 t1 = Thread(target=eat1,args=(name,)) 25 t2 = Thread(target=eat2,args=(name,)) 26 t1.start() 27 t2.start() 28 29 遞迴鎖解決死鎖問題