named threading locks

named locks are used in multi-threaded applications and based on the Python threading lock classes threading.Lock and threading.RLock. the advantage of the named locks in contrary to Python threading locks is that a lock don’t need to create and store a reference of a Python threading lock object - the NamedLocks does this automatically for your application and does keep track of all the named locks of your application in its class variables.

so a named lock get exclusively identified only by an unique string. and to create other blocking locks you only need a reference to the NamedLocks class.

named locks are very useful e.g. if you want to lock a certain record of database table. for this you simply create a new instance of the NamedLocks class and as unique string you can use the table name followed by the primary key of the record to lock:

named_lock = NamedLocks()
if named_lock.acquire(table_name + primary_key)

    ...     # locked database transaction code goes here

    named_lock.release(table_name + primary_key)

if now any other process of your application want to lock the same record (same table name and primary key) then it will be blocked until the process that acquired this named lock first is releasing the table record lock.

alternatively and especially if your application want to create multiple named locks you can use the class NamedLocks as a context manager, passing all the named lock strings to the constructor:

with NamedLocks(table_name1 + primary_key1, table_name2 + primary_key2, ...):
    ...     # locked database transaction


NamedLocks(*lock_names[, reentrant_locks, …])

manage all named locks of your application.

class NamedLocks(*lock_names, reentrant_locks=True, sys_lock=False)[source]

Bases: object

manage all named locks of your application.

migrated from answer in stackoverflow on the question


currently the sys_lock feature is not implemented. use either ae.lockfile or the github extension portalocker (see or the encapsulating extension ilock ( more on system wide named locking:

locks_change_lock: ClassVar[_thread.allocate_lock] = <unlocked _thread.lock object>

threading lock class variable used to change status of all NamedLock instances

active_locks: ClassVar[Dict[str, Union[_thread.allocate_lock, threading.RLock]]] = {}

class variable keeping a dictionary of all active RLock/Lock instances

active_lock_counters: ClassVar[Dict[str, int]] = {}

lock counters class variable for reentrant locks

__init__(*lock_names, reentrant_locks=True, sys_lock=False)[source]

prepare new named lock(s).

  • lock_names (str) – unique lock strings to be prepared to be locked by __enter__().

  • reentrant_locks (bool) – pass False to use non-reentrant locks (True=reentrant locks).

  • sys_lock (bool) – pass True to prepare system lock (works for several independent applications). CURRENTLY NOT IMPLEMENTED.


tuple of lock names

_lock_class: Type[Union[_thread.allocate_lock, threading.RLock]]

used threading lock class


True if lock will be system-wide (not only application-wide)


print function used to show debug and error messages


locking context enter method.

__exit__(exc_type, exc_val, exc_tb)[source]

locking context exit method.

dpo(*args, **kwargs)[source]

print function which is suppressing printout if debug level is too low.

acquire(lock_name, *args, **kwargs)[source]

acquire the named lock specified by the lock_name argument.

  • lock_name (str) – name of the lock to acquire.

  • args – passed to the acquire method of the underlying RLock respectively Lock class instance.

  • kwargs – passed to the acquire method of the underlying RLock or Lock class instance.

Return type



True if named lock got acquired successfully, else False.


release the named lock specified by the lock_name argument.


lock_name (str) – name of the lock to release.