100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Python

Multithreading in Python

How to run concurrent tasks with Python's threading module, and why the GIL limits CPU-bound parallelism.

Concurrency & Interview PrepIntermediate12 min readJul 7, 2026
Analogies

1. Introduction

Multithreading lets a Python program run several threads of execution concurrently within a single process, sharing the same memory space. It is most useful for I/O-bound tasks -- things like making network requests, reading/writing files, or waiting on a database -- where a thread spends most of its time waiting rather than computing. The threading module provides the Thread class along with synchronization primitives like Lock, Event, and Condition to coordinate access to shared data between threads.

🏏

Cricket analogy: During a rain-affected match, multiple ground staff work concurrently -- one covering the pitch, one clearing the outfield -- sharing the same stadium, which mirrors threads sharing one process's memory while each waits on separate tasks.

2. Syntax

python
import threading

def worker(name):
    print(f"Thread {name} is running")

t = threading.Thread(target=worker, args=("A",))
t.start()
t.join()

3. Explanation

A Thread object is created with a target callable and optional args/kwargs. Calling start() schedules the thread to begin running its target function, while join() blocks the calling thread until the target thread has finished executing -- this is essential when the main program needs to wait for background work to complete before continuing.

🏏

Cricket analogy: A team sends a substitute fielder onto the ground with start(), and the captain must wait (join()) for that fielder to return to the boundary before resuming the main game plan.

When multiple threads read and write the same shared variable without coordination, you get a race condition: the final result depends on unpredictable thread scheduling and can be wrong. Python's threading.Lock (a mutex) solves this -- a thread must acquire the lock before entering a critical section and release it afterward, guaranteeing that only one thread modifies the shared state at a time. The with lock: context manager form acquires and releases the lock automatically, even if an exception occurs.

🏏

Cricket analogy: Two scorers updating the same run total sheet at once without coordination can produce a wrong final score, so a single scorer must hold the 'pen' (lock) before writing, releasing it only after the entry is complete.

The Global Interpreter Lock (GIL) in CPython allows only one thread to execute Python bytecode at a time, even on a multi-core machine. This means threads do NOT achieve true CPU parallelism for CPU-bound work (e.g., number crunching) -- for that, use the multiprocessing module, where each process gets its own interpreter and GIL. Threading remains genuinely useful for I/O-bound work, because a thread releases the GIL while it waits on I/O, letting other threads run in the meantime.

4. Example

python
import threading

counter = 0
lock = threading.Lock()

def increment():
    global counter
    for _ in range(100000):
        with lock:
            counter += 1

threads = [threading.Thread(target=increment) for _ in range(4)]
for t in threads:
    t.start()
for t in threads:
    t.join()

print("Final counter value:", counter)

5. Output

text
Final counter value: 400000

6. Key Takeaways

  • threading.Thread runs a callable concurrently; start() launches it, join() waits for it to finish.
  • The GIL means CPython threads never run Python bytecode truly in parallel across cores.
  • Threading is ideal for I/O-bound tasks (network, disk, waiting), not CPU-bound number crunching.
  • Use multiprocessing for CPU-bound parallelism -- it sidesteps the GIL entirely.
  • Shared mutable state accessed by multiple threads must be protected with threading.Lock to avoid race conditions.
  • with lock: is the safest way to acquire/release a lock since it releases even on exceptions.

Practice what you learned

Was this page helpful?

Topics covered

#Python#PythonProgrammingStudyNotes#Programming#MultithreadingInPython#Multithreading#Syntax#Explanation#Example#StudyNotes#SkillVeris