~~並發編程(十二):死鎖和遞歸鎖~~


進擊のpython


並發編程——死鎖和遞歸鎖


死鎖是一種現象:

兩個及以上的進程或者線程在爭搶資源的過程中,出現的互相等待的現象

如果沒有外部干預,他們就一直僵持,永遠在互相等待,就“死”住了

看一下現象:

from threading import Thread, Lock


def func(A, B):
    A.acquire()
    print('A:這是func函數的開始.. ..')
    B.acquire()
    print('B:這是func函數的開始.. ..')
    B.release()
    print('B:這是func函數的結束!')
    A.release()
    print('A:這是func函數的結束!')


def inner(A, B):
    B.acquire()
    print('A:這是inner函數的開始.. ..')
    A.acquire()
    print('B:這是inner函數的開始.. ..')
    A.release()
    print('B:這是inner函數的結束!')
    B.release()
    print('A:這是inner函數的結束!')


def main(A, B):
    func(A, B)
    inner(A, B)


if __name__ == '__main__':
    A = Lock()
    B = Lock()
    for i in range(10):
        t = Thread(target=main, args=(A, B))
        t.start()

執行的時候就會出現阻塞情況(自己執行)

那我也想保護func里面的數據,也想保護inner里面的數據,應該怎么辦?


遞歸鎖

為了解決上述問題,遞歸鎖應運而生

為了支持在同一線程中多次請求同一資源,python就提供了重入鎖RLock

這個鎖就很有意思,他里面除了互斥鎖Lock以外,還有一個計數器counter

counter記錄了acquire的次數,從而使得資源可以被多次require

直到一個線程所有的acquire都被release,其他的線程才能獲得資源

上面的例子如果使用RLock代替Lock,則不會發生死鎖

二者的區別是:遞歸鎖可以連續acquire多次,而互斥鎖只能acquire一次

from threading import Thread, RLock


def func(A, B):
    A.acquire()
    print('A:這是func函數的開始.. ..')
    B.acquire()
    print('B:這是func函數的開始.. ..')
    B.release()
    print('B:這是func函數的結束!')
    A.release()
    print('A:這是func函數的結束!')


def inner(A, B):
    B.acquire()
    print('B:這是inner函數的開始.. ..')
    A.acquire()
    print('A:這是inner函數的開始.. ..')
    A.release()
    print('A:這是inner函數的結束!')
    B.release()
    print('B:這是inner函數的結束!')


def main(A, B):
    func(A, B)
    inner(A, B)


if __name__ == '__main__':
    B = A = RLock() # 區別在這!
    for i in range(10):
        t = Thread(target=main, args=(A, B))
        t.start()


*****
*****


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM