简体   繁体   中英

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?

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.

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.

This is make sense as its parameter's name: block . block=False provide a non-blocking function to access protected resources.

Example one:

You have a GUI thread and a background work thread. Your GUI thread needs to modify some data generated by work thread, but your GUI thread cannot block as it will block the whole interaction. So you can use lock.acquire(block=False) to safely check if data is ready without blocking.

Example two:

Another example related to event loop is asyncio , this provide a non-blocking access to protected resources.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM