Concurrency
Threading Basics
Creating and managing threads — the threading module, thread lifecycle, daemon threads, and when to use threads in Python.
Interview: Core concurrency concept — interviewers test understanding of threads, the GIL, and when threading helps vs hurts.
Threads allow concurrent execution within a single process. Python's threading module creates OS-level threads that share memory. Threads are ideal for I/O-bound tasks (network requests, file I/O) but limited for CPU-bound work due to the GIL.
Creating Threads
Thread(target=func, args=(...))— create a threadthread.start()— begin executionthread.join()— wait for thread to finishthread.is_alive()— check if still running
Thread Safety
- Threads share memory — race conditions possible on shared data
- Use
Lock,RLock, orSemaphorefor synchronization - Thread-safe data structures:
queue.Queue - GIL prevents true parallelism for CPU-bound work in CPython
Interview Insight
Know when threads help (I/O-bound) vs when they don't (CPU-bound due to GIL). Be able to explain thread safety and race conditions.
Use Cases
HTTP requests — downloading multiple URLs concurrently
File I/O — reading/writing multiple files in parallel
Database queries — executing independent queries concurrently
Web scraping — fetching multiple pages at once
Background tasks — daemon threads for periodic cleanup
Common Mistakes
Using threads for CPU-bound work — GIL prevents true parallelism, use multiprocessing
Not joining threads — main program may exit before threads finish
Sharing mutable data without locks — causes race conditions
Creating too many threads — overhead exceeds benefit, use a pool
Not handling exceptions in threads — they fail silently without proper handling