Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When would I acquire a lock with block state set to False?

I was wondering why ever setting block=false would make sense?

 from multiprocessing import Process, Lock
 lock.acquire(block=False)

If i don't need to block, I wouldn't use Lock at all?

like image 619
user1767754 Avatar asked Jan 29 '23 22:01

user1767754


2 Answers

From Python in a Nutshell:

L.acquire()
When blocking is True, acquire locks L . If L is already locked, the calling thread suspends and waits until L is unlocked, then locks L . Even if the calling thread was the one that last locked L , it still suspends and waits until another thread releases L . When blocking is False and L is unlocked, acquire locks L and returns True. When blocking is False and L is locked, acquire does not affect L , and returns False.

And a practical example using the following simple code:

from multiprocessing import Process, Lock, current_process


def blocking_testing(lock):
    if not lock.acquire(False):
        print('{} Couldn\'t get lock'.format(current_process().ident))
    else:
        print('{} Got lock'.format(current_process().ident))


if __name__ == '__main__':
    lock = Lock()
    for i in range(3):
        procs = []
        p = Process(target=blocking_testing, args=(lock,))
        procs.append(p)
        p.start()
        for p in procs:
            p.join()

With the above version (blocking=False) this outputs

12206 Got lock
12207 Couldn't get lock
12208 Couldn't get lock

If I set blocking=True (or remove it, as it defaults to True) the main process will hang, as the Lock is not being released. Finally, if I set blocking=True and add a lock.release() at the end, my output will be

12616 Got lock
12617 Got lock
12618 Got lock

I hope this was a clear enough explanation.

like image 153
Evyatar Meged Avatar answered Jan 31 '23 10:01

Evyatar Meged


multiprocessing.Lock is not used for blocking, it's used to protect one or more resources from concurrent access.

The simplest of the examples could be a file written by multiple processes. To guarantee that only one process at a time is writing on the given file, you protect it with a Lock.

There are situations where your logic cannot block. For example, if your logic is orchestrated by an event loop like the asyncio module, blocking would stop the entire execution until the Lock is released.

In such cases the common approach is trying to acquire the Lock. If you succeed, you proceed accessing the protected resource, otherwise you move to other routines and try later.

like image 29
noxdafox Avatar answered Jan 31 '23 10:01

noxdafox