How to implement a Lock with a timeout in Python 2.7

to elaborate on Steven’s comment suggestion:

import threading
import time

lock = threading.Lock()
cond = threading.Condition(threading.Lock())

def waitLock(timeout):
    with cond:
        current_time = start_time = time.time()
        while current_time < start_time + timeout:
            if lock.acquire(False):
                return True
            else:
                cond.wait(timeout - current_time + start_time)
                current_time = time.time()
    return False

Things to notice:

  • there are two threading.Lock() objects, one is internal to the threading.Condition().
  • when manipulating cond, it’s lock is acquired; the wait() operation unlocks it, though, so any number of threads can watch it.
  • the wait is embedded inside a for loop that keeps track of the time. threading.Condition can become notified for reasons other than timeouts, so you still need to track the time if you really want it to expire.
  • even with the condition, you still ‘poll’ the real lock, because its possible for more than one thread to wake and race for the lock. if the lock.acquire fails, the loop returns to waiting.
  • callers of this waitLock function should follow a lock.release() with a cond.notify() so that other threads waiting on it are notified that they should retry aquiring the lock. This is not shown in the example.

Leave a Comment