🧵
Advanced Python

Multithreading & the GIL

threading Module, GIL Ka Trap
💡 Python threading ek single kitchen mein multiple cooks jaisa hai, lekin sirf ek chaku (GIL — Global Interpreter Lock) hai — ek time par sirf ek cook Python code actually chala sakta hai, chahe kitne bhi threads ho. I/O wait (jaise oven mein pakna) ke waqt doosra cook kaam kar sakta hai.

Python ka GIL (Global Interpreter Lock) ek time par sirf EK thread ko Python bytecode execute karne deta hai — matlab CPU-heavy kaam (jaise heavy math) ke liye threading actual parallel speedup NAHI deta (C++/Java ke ulat). Ye Python ka ek well-known limitation hai.

Lekin I/O-bound tasks (file reading, network requests, database calls) ke liye threading bahut effective hai — jab ek thread I/O ka wait kar raha hota hai, GIL release ho jaata hai, aur doosra thread kaam kar sakta hai. CPU-bound parallelism ke liye multiprocessing module use hota hai (alag processes, apna-apna GIL).

import threading
import time

def download_file(name):
    print(f"{name} download shuru")
    time.sleep(2)   # I/O simulate — GIL release hota hai wait ke waqt
    print(f"{name} download complete")

threads = []
for i in range(3):
    t = threading.Thread(target=download_file, args=(f"file{i}",))
    threads.append(t)
    t.start()

for t in threads:
    t.join()   # sab threads ke complete hone ka wait karo

print("Sab downloads complete!")   # ~2 seconds mein (parallel I/O wait), 6 nahi
🧵
Python threading ek single kitchen mein multiple cooks jaisa hai, lekin sirf ek chaku (GIL — Global Interpreter Lock) hai — ek time par sirf ek cook Python code actually chala sakta hai, chahe kitne bhi threads ho. I/O wait (jaise oven mein pakna) ke waqt doosra cook kaam kar sakta hai.
1 / 6
⚡ झट से Recap
  • GIL = ek time par sirf ek thread Python code chalata hai
  • I/O-bound tasks (network, file) ke liye threading effective hai
  • CPU-bound tasks ke liye multiprocessing use karo, threading nahi
इस page में (2 subtopics)

multiprocessing module GIL ko bypass karta hai — har process apna alag Python interpreter (aur apna GIL) chalata hai, isliye TRUE parallel execution milta hai CPU-heavy tasks ke liye, threading ke ulat.

from multiprocessing import Pool

def square(n):
    return n * n

if __name__ == "__main__":
    with Pool(4) as p:                      # 4 parallel processes
        results = p.map(square, [1, 2, 3, 4, 5])
    print(results)   # [1, 4, 9, 16, 25] — actually parallel compute hua
⚠️Common Mistake: multiprocessing mein har process apni alag memory rakhta hai — variables share nahi hoti threading jaisi easily. Data share karne ke liye special multiprocessing.Queue/Value/Array chahiye hote hain.

asyncio ek aur approach hai concurrency ke liye — "cooperative multitasking" jaha ek single thread mein hi multiple tasks async/await ke through switch hote hain, especially I/O-heavy applications (web servers) ke liye popular.

import asyncio

async def fetch_data(name):
    print(f"{name} shuru")
    await asyncio.sleep(2)   # non-blocking wait
    print(f"{name} complete")

async def main():
    await asyncio.gather(
        fetch_data("Task1"),
        fetch_data("Task2"),
        fetch_data("Task3")
    )

asyncio.run(main())   # sab ~2 seconds mein complete (parallel-jaisa)
💡Tip: asyncio modern web frameworks (FastAPI) mein bahut popular hai — threading se bhi zyada efficient I/O-bound concurrency ke liye, lekin async/await syntax seekhna padta hai.