๐Ÿ Python Examples - Comprehensive Code Library
โ† Back to PranavKulkarni.org
Lesson 2 ยท Advanced

Concurrency & Threading

Understand the GIL, threading, and multiprocessing for CPU-bound tasks.

The Global Interpreter Lock (GIL)

The GIL is a mutex that protects access to Python objects, preventing multiple threads from executing Python bytecodes at once. This means multithreading in Python is great for I/O but not for CPU-bound tasks.

Threading (for I/O)

import threading

def worker(num):
    print(f"Thread {num} working")

threads = []
for i in range(5):
    t = threading.Thread(target=worker, args=(i,))
    threads.append(t)
    t.start()

Multiprocessing (for CPU)

To bypass the GIL and use multiple CPU cores, use the multiprocessing module, which creates separate memory spaces.

import multiprocessing

def compute(n):
    return n * n

if __name__ == '__main__':
    with multiprocessing.Pool(processes=4) as pool:
        results = pool.map(compute, range(100))

Choosing the Right Tool

Approach Best for Overhead
asyncioHigh-concurrency I/OVery Low
threadingStandard I/OLow
multiprocessingCPU-bound tasksHigh

โœ… Practice (30 minutes)

  • Write a CPU-heavy function (like calculating primes) and time its execution.
  • Run it using threading and observe no performance gain.
  • Run it using multiprocessing.Pool and see the speedup.
  • Use concurrent.futures.ThreadPoolExecutor for a simpler threading interface.