Do You Really Understand Python's GIL (Global Interpreter Lock)?(Python Core in Action 21)
Learn how Python's GIL impacts multithreading performance and explore ways to work around its limitations in your applications.
Welcome to the "Python Core in Action" Series
In previous lessons, we explored Python’s concurrency features and learned about multithreading.
However, there's an important topic related to Python multithreading—GIL (Global Interpreter Lock)—which is often misunderstood. Even many experienced Python engineers find GIL puzzling.
Today, I’ll explain GIL and help you understand it.
The Mystery
Let’s start with an example to show why GIL causes confusion.
Take this simple CPU-bound code:
def CountDown(n):
while n > 0:
n -= 1
Now, let’s use a large number, n = 100,000,000, and run `CountDown(n)` in a single thread.
On my 8-core MacBook, it takes 5.4 seconds. Next, I try multithreading to speed it up, as shown below:
from threading import Thread
n = 100000000
t1 = Thread(target=CountDown, args=[n // 2])
t2 = Thread(target=CountDown, args=[n // 2])
t1.start()
t2.start()
t1.join()
t2.join()
To my surprise, running this on the same machine doesn’t make it faster; instead, it slows down to 9.6 seconds.
I tried again with four threads, but the time was still around 9.8 seconds, similar to the two-thread result.
What's going on? Did I buy a fake MacBook?
Think about it for a moment, and maybe even test it on your machine.
I had two guesses.
First, I thought my machine was malfunctioning. To test this, I ran the same experiment on a single-core desktop.
This time, the single-thread run took 11 seconds, and so did the two-thread run.
Although it wasn’t slower than the single-threaded version like before, the results were the same.
This doesn’t seem to be a hardware issue. Python threads just aren’t working as expected. This led me to a second guess: are Python threads fake?
Python threads do wrap system-level threads—Pthreads in Linux and Windows threads in Windows.
Python threads are managed by the OS, handling things like memory, scheduling, and interrupts.
So, while Python threads abstract differently from C++ threads, their underlying mechanics are the same.