Concurrency
Multiprocessing
True parallelism with multiple processes — bypassing the GIL, process pools, shared memory, and inter-process communication.
Interview: Essential for CPU-bound performance — know when and how to use multiprocessing vs threading.
The multiprocessing module creates separate OS processes, each with its own Python interpreter and GIL. This enables true parallelism across multiple CPU cores for CPU-bound tasks. The tradeoff is higher memory usage and more complex data sharing.
Process vs Thread
- Process: Separate memory space, own GIL, true parallelism, higher overhead
- Thread: Shared memory, single GIL, limited parallelism, lower overhead
- Use processes for CPU-bound, threads for I/O-bound
Process Pools
Pool(processes=N)— create a pool of worker processespool.map(func, data)— distribute work across processespool.apply_async(func, args)— non-blocking submissionProcessPoolExecutor— higher-level API from concurrent.futures
Interview Insight
Know that multiprocessing bypasses the GIL for true CPU parallelism. Be able to explain the overhead tradeoff (serialization, memory) and when to use Pool vs Process directly.
Use Cases
CPU-bound computation — image processing, data transformation, simulations
Parallel data processing — splitting large datasets across cores
Scientific computing — parallelizing NumPy/pandas operations
Batch processing — running independent tasks across CPU cores
Machine learning — parallel model training or hyperparameter search
Common Mistakes
Forgetting if __name__ == "__main__" guard — required on Windows/macOS
Using multiprocessing for I/O-bound work — threads or asyncio is more efficient
Sharing complex objects without Manager — causes pickling errors
Not considering serialization overhead — data must be pickled between processes
Creating too many processes — match to CPU core count for best performance