What Is the Difference Between Multithreading and Multiprocessing?
Compare multithreading and multiprocessing: memory sharing, true parallelism, crash isolation, and when to choose each for I/O-bound or CPU-bound work.
Expected Interview Answer
Multithreading runs multiple threads within a single process sharing the same memory space, while multiprocessing runs multiple independent processes, each with its own isolated memory space, communicating only through explicit inter-process communication.
Multithreading is lightweight: threads share code, heap, and open files, so switching between them and communicating is cheap, but a bug in one thread (like corrupting shared memory) can crash the whole process, and in languages with a global interpreter lock, like CPython, threads cannot achieve true CPU-bound parallelism on multiple cores. Multiprocessing gives true parallelism across CPU cores because each process gets its own memory and its own interpreter/runtime instance, and one process crashing does not take down the others, but creating processes and communicating between them via pipes, queues, or shared memory segments is more expensive than using threads. The right choice depends on whether the workload is I/O-bound (multithreading often suffices) or CPU-bound (multiprocessing bypasses interpreter-level locks for true parallel speedup).
- Multithreading is lightweight and communicates via shared memory quickly
- Multiprocessing gives true parallelism across CPU cores
- Multiprocessing isolates crashes to a single process
- Multithreading suits I/O-bound work where waiting dominates
- Multiprocessing suits CPU-bound work needing real parallel computation
AI Mentor Explanation
Multithreading is like fielders on one team covering different parts of the ground, sharing the same scoreboard and captain, so coordinating a run-out needs just a shout. Multiprocessing is like fielding entirely separate teams on different grounds, each with its own scoreboard and captain, so one team's innings collapsing has zero effect on the other match.
Step-by-Step Explanation
Step 1
Multithreading: shared memory
Multiple threads run inside one process, sharing code, heap, and file descriptors, each with its own stack.
Step 2
Multithreading: cheap communication
Threads exchange data instantly via shared variables, but must use locks to avoid race conditions.
Step 3
Multiprocessing: isolated memory
Each process gets its own address space and its own copy of the interpreter/runtime.
Step 4
Multiprocessing: true parallelism
Since each process runs independently, CPU-bound work can run in real parallel across multiple cores, unaffected by any single interpreter lock.
Step 5
Multiprocessing: costlier communication
Processes must use IPC like pipes, queues, or shared memory segments to exchange data, which is slower than threads sharing memory.
What Interviewer Expects
- Explains memory sharing (threads) versus isolation (processes)
- Mentions the GIL or similar interpreter-level locks limiting thread parallelism
- Knows multiprocessing achieves true multi-core parallelism
- Distinguishes I/O-bound versus CPU-bound workload suitability
- Mentions IPC mechanisms processes must use to communicate
Common Mistakes
- Assuming multithreading always gives true parallel CPU speedup
- Forgetting multiprocessing has higher creation/communication overhead
- Not connecting the choice to I/O-bound versus CPU-bound workloads
- Ignoring crash isolation as a multiprocessing benefit
Best Answer (HR Friendly)
“Multithreading runs several smaller tasks inside one program that share the same memory, making them fast to coordinate but risky if one task corrupts shared data. Multiprocessing runs several fully separate copies of a program, each with its own private memory, which is safer and gives real parallel speed on multiple processor cores, at the cost of slower communication between them.”
Code Example
import threading, multiprocessing, time
def cpu_bound(n):
return sum(i * i for i in range(n))
# Threading: limited by the GIL for pure CPU-bound work in CPython
threads = [threading.Thread(target=cpu_bound, args=(10_000_000,)) for _ in range(4)]
# Multiprocessing: true parallel execution across cores
processes = [multiprocessing.Process(target=cpu_bound, args=(10_000_000,)) for _ in range(4)]
for p in processes: p.start()
for p in processes: p.join()
Follow-up Questions
- What is the Global Interpreter Lock and why does it limit threading?
- When would you choose multiprocessing over multithreading in Python?
- How do processes communicate given their isolated memory?
- What is the overhead cost of creating a new process versus a new thread?
- How does async I/O compare to multithreading for I/O-bound work?
MCQ Practice
1. What do threads in the same process share?
Threads within a process share the same address space, including code, heap, and open file descriptors.
2. Why does multiprocessing achieve true CPU parallelism where threading in CPython may not?
Because each process runs its own interpreter instance, they can execute truly in parallel across cores, sidestepping any single global interpreter lock.
3. Which workload type typically benefits more from multiprocessing?
CPU-bound work benefits from multiprocessing's true parallel execution across cores, while I/O-bound work often does fine with threading.
Flash Cards
What memory model does multithreading use? — Threads share the same process memory space, each keeping only its own stack.
What memory model does multiprocessing use? — Each process has its own isolated address space and runtime instance.
Which achieves true multi-core CPU parallelism more reliably? — Multiprocessing, since each process runs independently without a shared interpreter lock.
How do processes communicate given isolated memory? — Through IPC mechanisms like pipes, queues, or shared memory segments.