【问题标题】:python lock with-statement and timeoutpython lock with-statement和timeout
【发布时间】:2013-05-24 17:00:45
【问题描述】:

我正在使用这样的 Python 3 序列:

lock = threading.Lock()
res = lock.acquire(timeout=10)
if res:
    # do something ....
    lock.release()
else:
    # do something else ...

我更喜欢使用 with 语句而不是显式的“获取”和“释放”,但我不知道如何获得超时效果。

【问题讨论】:

  • 看来你做不到。
  • this 可能有帮助
  • 它看起来不像我想要的 ;-)。

标签: python-3.x locking with-statement


【解决方案1】:

您可以使用上下文管理器轻松完成此操作:

import threading
from contextlib import contextmanager

@contextmanager
def acquire_timeout(lock, timeout):
    result = lock.acquire(timeout=timeout)
    yield result
    if result:
        lock.release()


# Usage:
lock = threading.Lock()

with acquire_timeout(lock, 2) as acquired:
    if acquired:
        print('got the lock')
        # do something ....
    else:
        print('timeout: lock not available')
        # do something else ...

*注意:这在 Python 2.x 中不起作用,因为 Lock.acquire 没有 timeout 参数

【讨论】:

  • 这对我有用,谢谢。但是你能解释一下为什么在这种情况下使用with 时必须使用yield 吗?
  • @monkjuice 在上下文管理器中,yield 语句将控制权传递回调用者提供的with 块。所以yield resultresult 的值放入acquired 变量中并运行with acquire_timeout... 下面的缩进块,并在它返回后继续在上下文管理器中。
【解决方案2】:

稍微好一点的版本:

import threading
from contextlib import contextmanager


class TimeoutLock(object):
    def __init__(self):
        self._lock = threading.Lock()

    def acquire(self, blocking=True, timeout=-1):
        return self._lock.acquire(blocking, timeout)

    @contextmanager
    def acquire_timeout(self, timeout):
        result = self._lock.acquire(timeout=timeout)
        yield result
        if result:
            self._lock.release()

    def release(self):
        self._lock.release()

# Usage:
lock = TimeoutLock()

with lock.acquire_timeout(3) as result:
    if result:
        print('got the lock')
        # do something ....
    else:
        print('timeout: lock not available')
        # do something else ...

看来你不能继承threading.Lock,所以我不得不创建一个包装类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-19
    • 2016-09-13
    • 1970-01-01
    • 2019-12-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-05
    • 1970-01-01
    相关资源
    最近更新 更多