【问题标题】:How to properly try/catch timeout errors when acquiring a lock in Python 3.4在 Python 3.4 中获取锁时如何正确尝试/捕获超时错误
【发布时间】:2017-10-09 00:45:50
【问题描述】:

我将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 并在重试之间设置超时/延迟?

【问题讨论】:

    标签: python multithreading locking


    【解决方案1】:

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

    Lock.acquireRLock.acquire 如果获得锁则返回 True,否则返回 False。要测试您是否获得了锁,只需检查返回值。不要使用withtry-except

    【讨论】:

    • 啊!这是有道理的,为什么我会收到属性错误-它不是上下文管理器-谢谢!我想知道您是否也可以消除有关链接问题的困惑。我应该在这里使用条件变量吗?
    • @user138440:您不需要条件变量。链接的问题需要模拟timeout,因为Lock.acquireRLock.acquire 在Python 2 上不支持timeout
    猜你喜欢
    • 2023-04-07
    • 1970-01-01
    • 2013-09-09
    • 1970-01-01
    • 2018-08-20
    • 2018-03-26
    • 1970-01-01
    • 2016-01-21
    • 1970-01-01
    相关资源
    最近更新 更多