Are GIL and Thread-Safety synonyms?

October 24, 2013

After writing GIL - Global Interpreter Lock "GIL - Global Interpreter Lock"), a common question people ask me is:":

So the GIL ensures that my code is thread-safe, doesn't it?

Before I go into the nuts and bolts of it, let's start the other way around and check it with a practical example. Let's create a simple class that adds 1's to a var:

class Adding:
def __init__(self):
self.added = False
self.value = 0
def has_added(self):
return self.added
def add(self):
print "Adding...\n"
self.value +=1
self.added = True
def get_value(self):
return self.value

Now, let's create a few threads to run an object of that class and see what happens:

from threading import Thread
def do_add(adding):
if not adding.has_added():
adding = Adding()
for i in xrange(5):

Let's run this code a few times:

$ python thread_safety.py

$ python thread_safety.py


Ooops! We got it twice. Let's double check , and verify that the value is more than 1:

$ python thread_safety.py

Value: 1
$ python thread_safety.py


Value: 2

So, the answer to the question is No. What's happening then? If the GIL prevents two threads from running simultaneously, how can this be?

The problem with our code is that we introduced a race-condition. A race-condition happens when two or more threads are trying to access some shared data and then try to change it at the same time. The GIL ensures atomicity by interleaving the threads, meaning they can be stopped in the middle of their execution, and if a race-condition is present then we're in trouble. There are some ways to solve this, and I'll leave you with two simple solutions, to fix this:

P.S. I want to thank Vitor Torres, Ricardo Sousa and Nuno Silva for the reviews.

Ricardo Castro

Ricardo Castro

Software Engineering, DevOps, SRE, Taekwondo and Metal



© 2021