Threading in Python
What is a thread?
A thread is a unit of execution inside a process.
- One process can have multiple threads.
- Threads share the same memory of the process.
When to use threading
Threading is best for I/O-bound tasks:
- network requests
- reading/writing files
- waiting on APIs
When NOT to use threading
For CPU-bound tasks (heavy computation), Python threads are limited by the GIL (Global Interpreter Lock) in CPython.
For CPU-bound parallelism, prefer:
multiprocessingmultiprocessing- native extensions
The Global Interpreter Lock (GIL)
In CPython, only one thread executes Python bytecode at a time.
Practical takeaway:
- Threads can still improve performance when time is spent waiting (I/O).
- Threads won’t speed up CPU-only loops significantly.
Quick demo (I/O wait simulation)
import time
import threading
def task(i: int) -> None:
time.sleep(1)
print("done", i)
threads = []
start = time.time()
for i in range(5):
t = threading.Thread(target=task, args=(i,))
t.start()
threads.append(t)
for t in threads:
t.join()
print("seconds:", round(time.time() - start, 2))import time
import threading
def task(i: int) -> None:
time.sleep(1)
print("done", i)
threads = []
start = time.time()
for i in range(5):
t = threading.Thread(target=task, args=(i,))
t.start()
threads.append(t)
for t in threads:
t.join()
print("seconds:", round(time.time() - start, 2))Without threads, this would take about 5 seconds; with threads it’s ~1 second (because sleep is I/O wait).
Visualize it
A thread moves through a small lifecycle — created, started, running, sometimes waiting on I/O or a lock, then finished and joined back:
stateDiagram-v2 [*] --> New: Thread(target=fn) New --> Runnable: start() Runnable --> Running: scheduled (holds GIL) Running --> Waiting: I/O or lock Waiting --> Runnable: ready again Running --> Terminated: fn returns Terminated --> [*]: join()
The GIL means only one thread runs Python at a time — but the instant a thread waits on I/O it hands the GIL over, so another thread runs. That overlap is exactly why threading speeds up I/O-bound work (and why it doesn’t help CPU-bound work):
🧪 Try It Yourself
Exercise 1 – Create a Simple Thread
Exercise 2 – Join a Thread
Exercise 3 – Run Multiple Threads
If this helped you, consider buying me a coffee ☕
Buy me a coffeeWas this page helpful?
Let us know how we did
