【问题标题】:Python: Building a Reentrant Semaphore (combining RLock and Semaphore)Python:构建可重入信号量(结合 RLock 和信号量)
【发布时间】:2017-03-26 19:41:21
【问题描述】:

您将如何将threading.RLockthreading.Semaphore 结合起来?还是这样的结构已经存在?

在 Python 中,有一个可重入锁的原语threading.RLock(N),它允许同一个线程多次获取锁,但其他线程不能。还有threading.Semaphore(N),它允许在阻塞之前获取锁N次。如何将这两种结构结合起来?我希望最多 N 单独的线程能够获取锁,但我希望线程上的每个单独的锁都是可重入的。

【问题讨论】:

    标签: python multithreading locking semaphore


    【解决方案1】:

    所以我猜不存在可重入信号量。这是我想出的实现,很高兴招待 cmets。

    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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-16
      • 1970-01-01
      • 2017-08-24
      • 1970-01-01
      • 2013-07-15
      • 2015-10-09
      相关资源
      最近更新 更多