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 thethreading.Condition()
. - when manipulating
cond
, it’s lock is acquired; thewait()
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 alock.release()
with acond.notify()
so that other threads waiting on it are notified that they should retry aquiring the lock. This is not shown in the example.