Race condition in Python's threading🏁
Tags: python, async, programming
Published: 2024-02-26 05:00:00

we starting this blog let's quicky understand what's a race condition 🏎️

<img width="100%" style="width:100%" src=https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExbDd1Y2diejVzdGlhcm10cGoxcG1xcXZrMjllNHh2NzhwdngzNnk1bSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/l2JdXVTmHNtvlydzO/giphy.gif>

- Race condition is everywhere, we can see this b/w top cloud providers like AWS, GCP, Azure to acquire the position of Top cloud provider 
> now, with context of threading Race condtion leads to unexpected outcomes when multiple threads try to access and manipulate a single shared resource (file, varibales etc)

## intuitive doubt
- In the context of threading, race conditions arise when multiple threads attempt to access and manipulate a shared resource, such as a file or variable.

- You might wonder about the impact of the Global Interpreter Lock (GIL), which only allows one thread of a process to run at any given time. Despite this limitation, race conditions can still occur.

> let's take an example to better understand

```javascript
from threading import Thread, current_thread

class BookTicket():
    def __init__(self, available_seats):
        self.available_seats = available_seats
        
    def Bookseat(self, seatToBeBooked):
        print(f"{self.available_seats} seat was available before booking.")
        name = current_thread().name
        if seatToBeBooked <= self.available_seats:
            self.available_seats -= seatToBeBooked
            print(f"{seatToBeBooked} seat has been allocated to {name}")
        else:
            print("Sorry, we are out of seats.")
            
obj = BookTicket(1)
T1 = Thread(target=obj.Bookseat, kwargs={"seatToBeBooked": 1}, name="Walter White")
T2 = Thread(target=obj.Bookseat, kwargs={"seatToBeBooked": 1}, name="Jesse Pinkman")
T1.start()
T2.start()
```

> quick explanation on what's going in above code
 - so we have two threads namely walter white and jesse pinkman, and these threads are trying to book a seat, if the seat is available they are alloated with a seat else we say sorry we don't have seats available.
 - initially we have only 1 seat available with us and first thread T1(walter white) and then thread T2(jesse pink man) threads are executed

- now you might be expecting that we had 1 seat available, walter white would get that seat and after that we'd have 0 seats available for we'd say sorry jesse we don't have seats
- well this could be true but not always

![expected_execution](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9sgiamepof54ri6k6s74.png)

- above we can see the expected output but due to race condition this is'nt always true, 

---


![unexpected behaviour](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p19b0hr4ik8jco3fie2e.png)
- above is an example of race contion or an unexpected behaviour 

## now, let's understand how race condition comes into picture even with GIL
- so according to our expectations after `1 seat has been alloted to walter white`
- available seats should be 0, but it's 1 here and then it says sorry we are out of seats
- ideally after printing out this  `1 seat has been alloted to walter white`, 1 seat should have been reduced and next printed statement should have been 0 seat was available before booking(as we only had one seat initially whihc was alloated to walter white)

> but what really happened was after printing `1 seat has been alloted to walter white` a context switch happened and thread (T2/jesse pinkman) started executing and because the number of seats available was'nt deducted by first thread (T1/walter while, due to context switch) we got an unexpected result which said `1 seat available before booking` 
- and when again thread (T1/walter white) started executing from where it left before the context switch, number of available seats was subtracted now, then again context switch happened and thread (T2) started executing from where it left and as now the number of available seats was deducted by thraed T1,```sorry we are out of seats``` was printed.