python threading lock_python threading之死锁和可重入锁
一、死鎖
簡單來說,死鎖是一個(gè)資源被多次調(diào)用,而多次調(diào)用方都未能釋放該資源就會(huì)造成死鎖,這里結(jié)合例子說明下兩種常見的死鎖情況。
1、迭代死鎖
該情況是一個(gè)線程“迭代”請(qǐng)求同一個(gè)資源,直接就會(huì)造成死鎖:
import threading
import time
class MyThread(threading.Thread):
def run(self):
global num
time.sleep(1)
if mutex.acquire(1):
num = num+1
msg = self.name+' set num to '+str(num)
print msg
mutex.acquire()
mutex.release()
mutex.release()
num = 0
mutex = threading.Lock()
def test():
for i in range(5):
t = MyThread()
t.start()
if __name__ == '__main__':
test()
上例中,在run函數(shù)的if判斷中第一次請(qǐng)求資源,請(qǐng)求后還未 release ,再次acquire,最終無法釋放,造成死鎖。這里例子中通過將print下面的兩行注釋掉就可以正常執(zhí)行了 ,除此之外也可以通過可重入鎖解決,后面會(huì)提到。
2、互相調(diào)用死鎖
上例中的死鎖是在同一個(gè)def函數(shù)內(nèi)多次調(diào)用造成的,另一種情況是兩個(gè)函數(shù)中都會(huì)調(diào)用相同的資源,互相等待對(duì)方結(jié)束的情況。如果兩個(gè)線程分別占有一部分資源并且同時(shí)等待對(duì)方的資源,就會(huì)造成死鎖。
import threading
import time
class MyThread(threading.Thread):
def do1(self):
global resA, resB
if mutexA.acquire():
msg = self.name+' got resA'
print msg
if mutexB.acquire(1):
msg = self.name+' got resB'
print msg
mutexB.release()
mutexA.release()
def do2(self):
global resA, resB
if mutexB.acquire():
msg = self.name+' got resB'
print msg
if mutexA.acquire(1):
msg = self.name+' got resA'
print msg
mutexA.release()
mutexB.release()
def run(self):
self.do1()
self.do2()
resA = 0
resB = 0
mutexA = threading.Lock()
mutexB = threading.Lock()
def test():
for i in range(5):
t = MyThread()
t.start()
if __name__ == '__main__':
test()
這個(gè)死鎖的示例稍微有點(diǎn)復(fù)雜。具體可以理下。
二、可重入鎖
為了支持在同一線程中多次請(qǐng)求同一資源,python提供了“可重入鎖”:threading.RLock。RLock內(nèi)部維護(hù)著一個(gè)Lock和一個(gè)counter變量,counter記錄了acquire的次數(shù),從而使得資源可以被多次require。直到一個(gè)線程所有的acquire都被release,其他的線程才能獲得資源。這里以例1為例,如果使用RLock代替Lock,則不會(huì)發(fā)生死鎖:
import threading
import time
class MyThread(threading.Thread):
def run(self):
global num
time.sleep(1)
if mutex.acquire(1):
num = num+1
msg = self.name+' set num to '+str(num)
print msg
mutex.acquire()
mutex.release()
mutex.release()
num = 0
mutex = threading.RLock()
def test():
for i in range(5):
t = MyThread()
t.start()
if __name__ == '__main__':
test()
和例1不同之處在于threading.Lock()換成了threading.RLock() 。
總結(jié)
以上是生活随笔為你收集整理的python threading lock_python threading之死锁和可重入锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python百度手势识别_【百度大脑新品
- 下一篇: golang interface 类型转