考慮這種情況:如果一個線程遇到鎖嵌套的情況該怎麼辦,這個嵌套是指當我一個線程在擷取臨界資源時,又需要再次擷取。
根據這種情況,代碼如下:
Python代碼
''''' Created on 2012-9-8
@author: walfred @module: thread.ThreadTest6 '''
import threading import time
counter = 0 mutex = threading.Lock()
class MyThread(threading.Thread): def __init__(self): threading.Thread.__init__(self)
def run(self): global counter, mutex time.sleep(1); if mutex.acquire(): counter += 1 print "I am %s, set counter:%s" % (self.name, counter) if mutex.acquire(): counter += 1 print "I am %s, set counter:%s" % (self.name, counter) mutex.release() mutex.release()
if __name__ == "__main__": for i in range(0, 200): my_thread = MyThread() my_thread.start()
這種情況的代碼運作情況如下:
I am Thread-1, set counter:1
之後就直接挂起了,這種情況形成了最簡單的死鎖。
那有沒有一種情況可以在某一個線程使用互斥鎖通路某一個競争資源時,可以再次擷取呢?在Python中為了支援在同一線程中多次請求同一資源,python提供了“可重入鎖”:threading.RLock。這個RLock内部維護着一個Lock和一個counter變量,counter記錄了acquire的次數,進而使得資源可以被多次require。直到一個線程所有的acquire都被release,其他的線程才能獲得資源。上面的例子如果使用RLock代替Lock,則不會發生死鎖:
代碼隻需将上述的:
mutex = threading.Lock()
替換成:
mutex = threading.RLock()
即可。