As far as I know, the following code will be blocked if lock
is already acquired by another thread.
It seems that non-blocking can be implemented by lock.acquire(0)
, but instead I have to use try-finally
block instead with
block.
lock = threading.Lock()
def func():
with lock:
# do something...
Is there any method to implement non-blocking lock acquisition?
acquire allows a thread to take ownership of a lock. If a thread tries to acquire a lock currently owned by another thread, it blocks until the other thread releases the lock. At that point, it will contend with any other threads that are trying to acquire the lock.
In computer science, an algorithm is called non-blocking if failure or suspension of any thread cannot cause failure or suspension of another thread; for some operations, these algorithms provide a useful alternative to traditional blocking implementations.
A task (thread) is non-blocking when it doesn't cause other tasks (threads) to wait until the task is finished.
Lock can only be acquired once, and once acquired it cannot be acquired again by the same thread or any other thread until it has been released. A threading. RLock can be acquired more than once by the same thread, although once acquired by a thread it cannot be acquired by a different thread until it is been released.
@contextmanager
def nonblocking(lock):
locked = lock.acquire(False)
try:
yield locked
finally:
if locked:
lock.release()
lock = threading.Lock()
with nonblocking(lock) as locked:
if locked:
do_stuff()
Is there any method to implement non-blocking lock acquisition?
Yes. Just raise an exception if the lock can't be acquired immediately. Something like:
@contextlib.contextmanager
def non_blocking_lock(lock=threading.Lock()):
if not lock.acquire(blocking=False):
raise WouldBlockError
try:
yield lock
finally:
lock.release()
Usage:
with non_blocking_lock():
# run with the lock acquired
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With