Threading in Python
Threading
Section titled “Threading”Introduction
Section titled “Introduction”Threads are lightweight processes that share the same memory space. Python threads are great for I/O-bound tasks but limited for CPU-bound tasks by the GIL.
Creating Threads
Section titled “Creating Threads”import threadingimport time
def worker(name, delay): time.sleep(delay) print(f"Worker {name} finished")
# Create threadst1 = threading.Thread(target=worker, args=("A", 2))t2 = threading.Thread(target=worker, args=("B", 1))
# Start threadst1.start()t2.start()
# Wait for completiont1.join()t2.join()print("All done")Thread Pools
Section titled “Thread Pools”from concurrent.futures import ThreadPoolExecutorimport time
def fetch_url(url): time.sleep(1) return f"Data from {url}"
urls = ["http://example.com"] * 5
# Using ThreadPoolExecutorwith ThreadPoolExecutor(max_workers=3) as executor: results = list(executor.map(fetch_url, urls)) print(results)Thread Safety with Locks
Section titled “Thread Safety with Locks”import threading
counter = 0lock = threading.Lock()
def increment(): global counter for _ in range(100000): with lock: # Acquire and release automatically counter += 1
threads = [threading.Thread(target=increment) for _ in range(5)]for t in threads: t.start()for t in threads: t.join()print(f"Counter: {counter}") # Always 500000RLock (Reentrant Lock)
Section titled “RLock (Reentrant Lock)”lock = threading.RLock() # Same thread can acquire multiple times
def recursive_lock(n): with lock: if n > 0: recursive_lock(n - 1)Semaphore and Event
Section titled “Semaphore and Event”# Semaphore — limits concurrent accesssemaphore = threading.Semaphore(3) # Max 3 threads at once
def limited_worker(): with semaphore: print("Working...") time.sleep(1)
# Event — signaling between threadsevent = threading.Event()
def waiter(): print("Waiting for event...") event.wait() print("Event received!")
def setter(): time.sleep(2) event.set()
threading.Thread(target=waiter).start()threading.Thread(target=setter).start()When to Use Threading
Section titled “When to Use Threading”| Task Type | Use Threads? | Alternative |
|---|---|---|
| I/O-bound (web requests, file I/O) | ✅ Yes | asyncio |
| CPU-bound (calculations) | ❌ No (GIL) | multiprocessing |
| Many concurrent connections | ⚠️ Limited | asyncio |
Practice Exercises
Section titled “Practice Exercises”Exercise 1: Download multiple URLs concurrently using a thread pool.
Exercise 2: Implement a thread-safe producer-consumer queue using threading primitives.