How to create a non blocking Thread Lock in Python

In this tutorial we will explore how to create a non blocking thread lock in Python.

By default, whenever we attempt to acquire a thread lock, the thread will wait for it indefinitely (forever). We may wish to change this behavior, which is what we will be demonstrating in this tutorial.


Non Blocking Thread Locks

There is no difference in the type of Lock used for non-blocking and blocking threads. We will still be using the same Lock Class, and creating the Lock in the same way.

from threading import Thread, Lock

lock = Lock()

We cannot actually make a “non-blocking lock”, rather we can attempt to “acquire” it in a non-blocking way. This means we need make a modification to our acquire() method.

The syntax for the acquire() function is shown below:

lock.acquire(blocking = boolean)

(Do note that blocking is an optional parameter with a default value of true)

If blocking=true, then the acquire() will not pause the execution of the thread if the lock has already been acquired by another thread. It will simply return “false” and continue the execution of the thread.

Here is a small example.

from threading import Thread, Lock
from time import sleep

lock = Lock()

def func(lock):
    while True:
        if lock.acquire(blocking=False):
            # Enter Critical Section
            print("Do some work....")
            break
        else:
            print("Do some other work")
            sleep(5)
    lock.release()

thread = Thread(target= func, args= (lock,))
thread.start()
thread.join()
Do some work....

As you can see from the output, the thread was able to successfully acquire the lock because it was free. Now let’s take a look at another example where the lock was already acquired by another thread.


Example# 2

In this example a second thread called blocking_thread will acquire the lock first for 10 seconds. What we want to really show here is how we can improve performance in multithreaded applications.

Instead of making our thread wait 10 seconds, we let it do some other work instead that does not rely on the critical section or the shared resource. This improves efficiency and is one of the many techniques we can use to speed up our computations.

from threading import Thread, Lock
from time import sleep

lock = Lock()

def blocking_func(lock):
    lock.acquire()
    sleep(10)
    lock.release()

def func(lock):
    while True:
        if lock.acquire(blocking=False):
            print("Do some work....")
            break
        else:
            print("Doing some other work")
            sleep(5)
    lock.release()

blocking_thread = Thread(target= blocking_func, args= (lock,))
thread = Thread(target= func, args= (lock,))

blocking_thread.start()
thread.start()

blocking_thread.join()
thread.join()
Doing some other work
Doing some other work
Do some work....

Another interesting and rather similar parameter in the acquire() function is timeout. Check it out if you are interested!


This marks the end of the How to create a non blocking Thread Lock in Python Tutorial. Any suggestions or contributions for CodersLegacy are more than welcome. Questions regarding the tutorial content can be asked in the comments section below.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments