vdboor
vdboor

Reputation: 22526

How can another Python thread wait until a lock is released?

Given this code, how can I make sure that get_model() can always be called without waiting, unless reload_lock is active?

Preferably, I don't want get_model() to aquire the reload_lock itself, as all threads may freely call this method unless the application is reloading it's models.

import threading

reload_lock = threading.Lock()


def get_model(name):
    # Normally this can be called, unless reload_models() is active
    # e.g. "if reload_lock.locked() -> wait until lock is released.
    ...


def reload_models():
    try:
        reload_lock.acquire()
        ...  # reload models
    finally:
        reload_lock.release()

Upvotes: 1

Views: 6034

Answers (2)

Edward Spencer
Edward Spencer

Reputation: 649

I was using thread locks for asynchronous user input on many functions and wanted something a bit more re-usable where the user input wouldn't be missed because the lock happened to be locked at that instance. So I bundled up checking the locks into a wrapper with a bit of a wait loop attached;

import threading
from functool import wraps
from time import sleep

lock = threading.Lock()

def wait_lock(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        while lock.locked():
            sleep(0.001)
        lock.acquire()
        func(*args, **kwargs)
        lock.release()
    return wrapper

You could also add a timeout on the while loop in case you accidentally threadlock yourself.

Upvotes: 3

Károly Szabó
Károly Szabó

Reputation: 1273

Maybe you should try like this, in the get_model():

if reload_lock.locked():
    reload_lock.acquire()
    reload_lock.release()

I know it's an acquire, but can be a solution if you instantly release it.

Upvotes: 4

Related Questions