Deadlock of threads in python

The deadlock of Threads in Python

In this post, we will discuss the concept of the Deadlock of Threads in Python. 

In the previous chapter, we discussed Thread Synchronization in Python using Locks and Semaphores and how we can perform synchronization when multiple threads are running in a program. Though it is possible to synchronize the threads, there could also be chances for the threads to land in a Deadlock. 

Let me tell you what Deadlock is in layman’s terms. For example, you are a programmer and developed a logic to book and cancel seats for bus service. Since booking and cancelling are opposite, you set the code in such a way that the thread related to booking decreases the availability of the seats, and the thread pertaining to the cancellation increases the availability of the seats. 

What if both the threads are acting at the same time? There could be a chance that both threads lock the same object and wait for each other to release the lock. This waiting time can probably take longer and forever, and this sort of situation is called the Deadlock of threads in Python.

Deadlock in Python Illustration-1

Let us now go through a program to witness the situation of Deadlock in Python.

#Python program to understand the concept of Deadlocks

from threading import *
from time import sleep

#declare two locks
lock1 = Lock()
lock2 = Lock()

#create a function for booking the seat in bus
def bookBusTicket():
  lock1.acquire()
  print('bookBusTicket locked the bus')
  print('bookBusTicket wants to lock the seat')
  sleep(2)
  lock2.acquire()
  print('bookBusTicket locked seat')
  lock2.release()
  lock1.release()
  print('Booking of ticket has been completed.')

#create a function for cancelling bus ticket
def cancelBusTicket():
  lock2.acquire()
  print('cancelBusTicket locked seat')
  print('cancelBusTicket wants to lock the bus')
  lock1.acquire()
  print('cancelBusTicket locked the bus')
  lock1.release()
  lock2.release()
  print('Cancellation has been done successfully')

#create two threads and run the the threads
thread1 = Thread(target=bookBusTicket)
thread2 = Thread(target=cancelBusTicket)
thread1.start()
thread2.start()
Output:

bookBusTicket locked the bus
bookBusTicket wants to lock the seat
cancelBusTicket locked seat
cancelBusTicket wants to lock the bus
^CException ignored in: <module 'threading' from '/usr/lib/python3.10/threading.py'>
Traceback (most recent call last):
  File "/usr/lib/python3.10/threading.py", line 1560, in _shutdown
    lock.acquire()
KeyboardInterrupt: 

In the above program, you can notice that the other execution is halted, and we had to use CTRL + C to force quit the execution. If we had not quit forcefully, the two threads would have continued to be in lock state forever. This situation is called ‘Deadlock‘. 

When a program lands in a Deadlock, any further execution of the program goes into a pause state, affecting the application’s performance. As a developer, you are responsible for ensuring that the deadlocks don’t occur. 

How to avoid the Deadlock of threads in a Python program? 

You cannot find a rule book to avoid deadlocks in a program. As a developer, your number one responsibility is to ensure you write good code that avoids deadlocks. For instance, the same program mentioned above would work fine without the sleep() function and execute the program successfully.

#The same program mentioned above only with one difference 
#We commented the sleep() function in this program to make the execution successful. 

from threading import *
from time import sleep

#declare two locks
lock1 = Lock()
lock2 = Lock()

#create a function for booking the seat in bus
def bookBusTicket():
  lock1.acquire()
  print('bookBusTicket locked the bus')
  print('bookBusTicket wants to lock the seat')
  #sleep(2)
  lock2.acquire()
  print('bookBusTicket locked seat')
  lock2.release()
  lock1.release()
  print('Booking of ticket has been completed.')

#create a function for cancelling bus ticket
def cancelBusTicket():
  lock2.acquire()
  print('cancelBusTicket locked seat')
  print('cancelBusTicket wants to lock the bus')
  lock1.acquire()
  print('cancelBusTicket locked the bus')
  lock1.release()
  lock2.release()
  print('Cancellation has been done successfully')

#create two threads and run the the threads
thread1 = Thread(target=bookBusTicket)
thread2 = Thread(target=cancelBusTicket)
thread1.start()
thread2.start()
Output:

bookBusTicket locked the bus
bookBusTicket wants to lock the seat
bookBusTicket locked seat
Booking of ticket has been completed.
cancelBusTicket locked seat
cancelBusTicket wants to lock the bus
cancelBusTicket locked the bus
Cancellation has been done successfully

We hope you have understood the concept of Deadlocks in Python. Build the habit of coding regularly to gain more practice and not land in situations like Deadlock in your Python programs. 

Scroll to Top