Threading Module
TL;DR
The threading
module enables concurrent execution through threads with synchronization primitives like Lock, Event, and Semaphore for safe resource sharing.
Interesting!
Python’s Global Interpreter Lock (GIL) means only one thread executes Python code at once - threading helps with I/O-bound tasks, not CPU-bound ones!
Creating Threads
python code snippet start
import threading
import time
def worker(name, delay):
print(f"Worker {name} starting")
time.sleep(delay)
print(f"Worker {name} finished")
# Create and start threads
threads = []
for i in range(3):
t = threading.Thread(target=worker, args=(f"Thread-{i}", 2))
threads.append(t)
t.start()
# Wait for all to complete
for t in threads:
t.join()
python code snippet end
Thread Synchronization
python code snippet start
import threading
# Shared resource protection
lock = threading.Lock()
counter = 0
def increment():
global counter
with lock: # Automatically acquire/release
counter += 1
# Event signaling
event = threading.Event()
def waiter():
event.wait() # Block until event is set
print("Event received!")
def setter():
time.sleep(2)
event.set() # Signal waiting threads
python code snippet end
Semaphore for Resource Limiting
python code snippet start
# Limit concurrent access to resource
semaphore = threading.Semaphore(2) # Max 2 threads
def limited_resource(thread_id):
with semaphore:
print(f"Thread {thread_id} accessing resource")
time.sleep(3)
print(f"Thread {thread_id} releasing resource")
python code snippet end
Thread-Safe Communication
python code snippet start
import queue
import threading
# Thread-safe queue
q = queue.Queue()
def producer():
for i in range(5):
q.put(f"item-{i}")
print(f"Produced item-{i}")
def consumer():
while True:
item = q.get()
if item is None:
break
print(f"Consumed {item}")
q.task_done()
python code snippet end
Best Practices
- Use
with
statements for locks to ensure release - Call
join()
to wait for thread completion - Use
queue.Queue
for thread-safe data exchange - Consider
concurrent.futures
for simpler thread pools
Threading excels at I/O-bound tasks where threads spend time waiting - perfect for web scraping, file operations, and network requests! Compare threading with asyncio for async I/O and multiprocessing for CPU-bound tasks . For thread-safe data handling, use SQLite databases and thread-safe logging .
Reference: threading — Thread-based parallelism