2016-11-12 161 views
0

如何結合threading.RLockthreading.Semaphore?還是這樣的結構已經存在?Python:構建可重入信號量(結合RLock和信號量)

在Python中,有一個可重入鎖的原語,threading.RLock(N),它允許同一個線程多次獲取一個鎖,但是沒有其他線程可以。還有threading.Semaphore(N),它允許在鎖定之前獲得鎖定N次。如何結合這兩種結構?我想最多N單獨的線程能夠獲得鎖,但我希望線程上的每個單獨的鎖是一個可重入的線程。

回答

0

所以我猜一個可重入信號量不存在。這是我提出的實現,很樂意接受評論。

import threading 
import datetime 
class ReentrantSemaphore(object): 
    '''A counting Semaphore which allows threads to reenter.''' 
    def __init__(self, value = 1): 
    self.local = threading.local() 
    self.sem = threading.Semaphore(value) 

    def acquire(self): 
    if not getattr(self.local, 'lock_level', 0): 
     # We do not yet have the lock, acquire it. 
     start = datetime.datetime.utcnow() 
     self.sem.acquire() 
     end = datetime.datetime.utcnow() 
     if end - start > datetime.timedelta(seconds = 3): 
     logging.info("Took %d Sec to lock."%((end - start).total_seconds())) 
     self.local.lock_time = end 
     self.local.lock_level = 1 
    else: 
     # We already have the lock, just increment it due to the recursive call. 
     self.local.lock_level += 1 

    def release(self): 
    if getattr(self.local, 'lock_level', 0) < 1: 
     raise Exception("Trying to release a released lock.") 

    self.local.lock_level -= 1 
    if self.local.lock_level == 0: 
     self.sem.release() 

    __enter__ = acquire 
    def __exit__(self, t, v, tb): 
    self.release()