dragon.native.lock

The Dragon native lock provides basic synchronization functionality between processes and threads.

Importantly, a Lock() can be released by any process or thread, while a recursive RLock() needs to be released by the process & thread that called it.

Our implementation also extends the API by a few methods that are internal in Python Multiprocessing, but are used very frequently, thus appear useful for everyone.

Classes

Lock

Dragon native Lock implementation based on a channel with a capacity of 1.

class Lock

Bases: object

Dragon native Lock implementation based on a channel with a capacity of 1.

Once a process or thread has acquired a lock, subsequent attempts to acquire it from any process or thread will block until it is released; any process may release it.

Recursive use is supported by means of the ‘recursive’ parameter. A recursive lock must be released by the process or thread that acquired it. Once a process or thread has acquired a recursive lock, the same process or thread may acquire it again without blocking; that process or thread must release it once for each time it has been acquired.

Lock supports the context manager protocol and thus may be used in ‘with’ statements.

__init__(m_uid: int = 4611686018427387904, recursive: bool = False)

Initialize the lock object

Parameters:
  • m_uid (int, optional) – memory pool to create the channel in, defaults to _DEF_MUID

  • recursive (bool, optional) – if the Lock should be recursive, defaults to False

acquire(block: bool = True, timeout: float | None = None) bool

Acquire a lock, blocking or non-blocking.

If the lock is not recursive:

With the block argument set to True (the default), the method call will block until the lock is in an unlocked state, then set it to locked and return True.

With the block argument set to False, the method call does not block. If the lock is currently in a locked state, return False; otherwise set the lock to a locked state and return True. When invoked with a positive, floating-point value for timeout, block for at most the number of seconds specified by timeout as long as the lock can not be acquired. Invocations with a negative value for timeout are equivalent to a timeout of zero. Invocations with a timeout value of None (the default) set the timeout period to infinite. The timeout argument has no practical implications if the block argument is set to False and is thus ignored. Returns True if the lock has been acquired or False if the timeout period has elapsed.

If the lock is recursive, repeated calls to a lock already owned by the current process return True and increment the recursion level. Release() has then be called an equal amount of times by the same process to free the lock.

Parameters:
  • block (bool, optional) – should the call block at all, defaults to True

  • timeout (float, optional) – how long to block in seconds, ignored if block=False, defaults to None

Returns:

if the lock was acquired

Return type:

bool

release() None

Release a lock.

If the lock is not recursive: This can be called from any process or thread, not only the process or thread which originally acquired the lock.

If the lock is recursive: Decrement the recursion level. If after the decrement the recursion level is zero, reset the lock to unlocked (not owned by any process or thread) and if any other processes or threads are blocked waiting for the lock to become unlocked, allow exactly one of them to proceed. If after the decrement the recursion level is still nonzero, the lock remains locked and owned by the calling dragon process and thread.

Raises:
  • ValueError – if the lock has not been acquired before

  • AssertionError – if the lock is recursive and not held by the caller

is_recursive() bool

Return True if this lock is recursive, i.e. can be called multiple times by the same thread/process.

Returns:

recursiveness of the lock

Return type:

bool

is_mine() bool

Return True if this rlock is owned by the caller process & thread

Returns:

ownership of the lock

Return type:

bool

count() int

How often this lock has been acquired. Will return only 0 or 1 for a non-recursive Lock. :return: The number of times this lock has been acquired :rtype: int