18

次のような Python 3 シーケンスを使用しています。

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

明示的な「取得」と「解放」の代わりに with ステートメントを使用したいのですが、タイムアウト効果を得る方法がわかりません。

4

2 に答える 2

16

これは、コンテキスト マネージャーを使用して非常に簡単に行うことができます。

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 では引数がないため、これは機能しません。timeoutLock.acquire

于 2013-05-28T01:00:44.517 に答える
9

少し良いバージョン:

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ので、代わりにラッパー クラスを作成する必要がありました。

于 2013-05-28T01:17:34.273 に答える