次のような Python 3 シーケンスを使用しています。
lock = threading.Lock()
res = lock.acquire(timeout=10)
if res:
# do something ....
lock.release()
else:
# do something else ...
明示的な「取得」と「解放」の代わりに with ステートメントを使用したいのですが、タイムアウト効果を得る方法がわかりません。
次のような Python 3 シーケンスを使用しています。
lock = threading.Lock()
res = lock.acquire(timeout=10)
if res:
# do something ....
lock.release()
else:
# do something else ...
明示的な「取得」と「解放」の代わりに with ステートメントを使用したいのですが、タイムアウト効果を得る方法がわかりません。
これは、コンテキスト マネージャーを使用して非常に簡単に行うことができます。
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 では引数がないため、これは機能しません。timeout
Lock.acquire
少し良いバージョン:
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
ので、代わりにラッパー クラスを作成する必要がありました。