在Python 3.4中获取锁时如何正确尝试/捕获超时错误

时间:2017-10-09 00:45:50

标签: python multithreading locking

我正在使用threading.RLock作为多线程应用程序。我想让线程尝试获取锁,如果不成功,请重试一些次数,前提是重试的时间低于某个超时阈值。

这就是我所拥有的

>>> import threading
>>> lock = threading.RLock()
>>> def worker():
        with lock.acquire(timeout=5):
            print('acquired')
>>> lock.acquire()
>>> t2 = threading.Thread(target=worker)
>>> t2.start()

这似乎有效,等待五秒后我得到一个例外:

>>> Exception in thread Thread-1:
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/threading.py", line 920, in _bootstrap_inner
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/threading.py", line 868, in run
    self._target(*self._args, **self._kwargs)
  File "<pyshell#7>", line 2, in test
AttributeError: __exit__

KeyboardInterrupt
>>> 
KeyboardInterrupt

AttributeError似乎很奇怪 - 我们不应该看到某种超时错误吗?

我的问题是:

  1. 我是否在Python 3.4中正确执行此操作?我一直在寻找一个似乎针对Python 2.7的similar question asked on SO。此外,我有点困惑,如果lock.acquire接受超时参数,我需要使用条件变量。
  2. 在重试之间有超时/延迟重试lock.acquire是否有更好的模式?

1 个答案:

答案 0 :(得分:0)

锁是上下文管理器,但drop没有返回上下文管理器。如果它超时,它也不会抛出异常。

acquireLock.acquire如果获得锁定则返回RLock.acquire,如果他们没有,则返回True。要测试是否获得了锁定,只需检查返回值。请勿使用Falsewith - try