python lock with-statement and timeout

后端 未结 2 1730
无人共我
无人共我 2021-02-05 13:43

I am using a Python 3 sequence like this:

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


        
相关标签:
2条回答
  • 2021-02-05 14:23

    You can do this pretty easily with a context manager:

    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 ...
    

    *Note: This won't work in Python 2.x since there isn't a timeout argument to Lock.acquire

    0 讨论(0)
  • 2021-02-05 14:29

    Slightly nicer version:

    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 ...
    

    It appears you can't subclass threading.Lock, so I had to make a wrapper class instead.

    0 讨论(0)
提交回复
热议问题