Sitemap

Advanced Python 4— GIL in Python

5 min readFeb 4, 2026

--

If you work with threads in Python, you will often hear about the GIL, or Global Interpreter Lock.

What is GIL?

The GIL allows only one thread to execute Python code at a time, even on a multi-core CPU.

So even if your program has multiple threads, only one thread runs Python instructions at any moment.

It is a mechanism in CPython (the standard Python interpreter).

✔ Only ONE thread executes Python bytecode at a time
✔ Even on multi-core CPUs

Why Does Python Have a GIL?

The GIL exists to:

Press enter or click to view image in full size
Press enter or click to view image in full size

The GIL makes sure Python objects are not deleted while another thread is still using them, keeping memory management safe.

Press enter or click to view image in full size
Press enter or click to view image in full size
Press enter or click to view image in full size

The GIL is a trade-off: it limits CPU-bound threading but keeps Python simple, safe, and fast for most programs.

Example:

import threading

def count():
x = 0
for _ in range(100_000_000):
x += 1

t1 = threading.Thread(target=count)
t2 = threading.Thread(target=count)

t1.start()
t2.start()

t1.join()
t2.join()

What you might expect

  • Two threads
  • Two CPU cores
  • Program runs twice as fast

What actually happens

  • Due to the GIL, only one thread runs at a time
  • Threads take turns using the CPU
  • No real speed improvement

Threads do not help for CPU-heavy work in Python

Threads are concurrent, not parallel (for Python code).

When Threads Still Help (I/O-bound Tasks)

The GIL is released when a thread is waiting for I/O.

Example:

  • Reading a file
  • Waiting for a network response
  • Calling an API

Threads are useful for I/O-bound tasks

How to Bypass the GIL

Using native (C/C++) extensions.

Why?

✔ Extensions can release GIL manually
✔ Allow true parallel execution

Many high-performance libraries:

Get Abhishek Jain’s stories in your inbox

Join Medium for free to get updates from this writer.

✔ NumPy
✔ PyTorch
✔ TensorFlow

Why fast?

➡️Heavy work done in C/C++
➡️GIL released during computation

Even though you write Python code, many libraries are actually:

✔ Implemented in C / C++ / CUDA
✔ Python is just a wrapper / interface

Your Python code acts like:

➡️ A remote control
➡️ Calling fast native code underneath

Press enter or click to view image in full size
Press enter or click to view image in full size

When we call a NumPy function from Python, the function we invoke is typically implemented in optimized C (or C++) code underneath. The Python layer acts as a wrapper that forwards the request to NumPy’s native backend through a well-defined API. The actual computation is then performed in compiled native code (Compiled native code means code that has been translated directly into machine instructions that the CPU can execute), which runs much faster than Python bytecode. During this execution, Python’s interpreter overhead is avoided (Python interpreter overhead is largely avoided during the heavy computation, because the actual work is executed by compiled native C/C++ code.) and in many cases the GIL is released. Once the computation finishes, the result is passed back through the API to the Python layer. Python then presents the final output to the user as a normal Python object. This design is the reason NumPy operations are significantly faster than equivalent logic written using pure Python loops.

Press enter or click to view image in full size

Why GIL is not a problem here

Because:

✔ Native code runs outside Python interpreter
✔ Libraries release GIL
✔ Multiple threads can run native code

Use multiprocessing

Each process has:

  • Its own Python interpreter
  • Its own GIL
from multiprocessing import Process

def count():
x = 0
for _ in range(100_000_000):
x += 1

p1 = Process(target=count)
p2 = Process(target=count)

p1.start()
p2.start()

p1.join()
p2.join()

Now:

  • Processes run in parallel
  • Multiple CPU cores are used

Common Misunderstandings

❌ “Python cannot use multiple cores”
✅ Python can, using processes

❌ “Threads are useless in Python”
✅ Threads are great for I/O-bound tasks

Rule of thumb:

  • Use threads for I/O-bound work
  • Use processes for CPU-bound work

Why C/C++ doesn’t have GIL?

Press enter or click to view image in full size

C and C++ don’t need a GIL because they don’t manage memory automatically or run code inside a shared interpreter — thread safety is left to the programmer.

--

--