Shared Memory & Queues
Shared Memory and IPC Queues
Because processes do not share a virtual memory space by default, data exchange between them requires specialized Inter-Process Communication (IPC) mechanisms. Python's multiprocessing module offers two distinct communication paradigms: Message Passing (via Queues and Pipes) and Shared Memory (via Value, Array, Manager, and Python 3.8+'s zero-copy shared_memory).
1. Message Passing: multiprocessing.Queue vs Pipe
multiprocessing.Queue
Similar in API to queue.Queue, but backed by underlying OS pipes and background feeder threads that serialize (pickle) objects across process boundaries:
multiprocessing.Pipe
Provides a direct, low-latency, two-way (or one-way) connection between exactly two processes:
2. Basic Shared State: Value and Array
For lightweight primitives, multiprocessing.Value and multiprocessing.Array allocate synchronized C-level data structures (ctypes) in shared memory:
3. Python 3.8+ Zero-Copy Shared Memory (multiprocessing.shared_memory)
When processing massive datasets (such as 4K video frames, large Pandas DataFrames, or multi-gigabyte NumPy tensors), pickling data across pipes induces massive CPU and memory serialization overhead.
Python 3.8 introduced multiprocessing.shared_memory.SharedMemory, allocating named shared memory segments managed directly by the operating system kernel. Processes map directly to this memory via memoryview, achieving true zero-copy parallel data manipulation:
4. Resource Cleanup Invariant: close() vs unlink()
shared_memory.SharedMemory:
- Calling shm.close() detaches the current process from the memory block.
- Calling shm.unlink() instructs the operating system kernel to destroy and deallocate the shared memory segment.
Failing to call unlink() on the creator process causes an OS-level memory leak that persists even after the Python process terminates.5. Architectural Summary Table
| Mechanism | Serialization Cost | Flexibility | Best Use Case |
|---|---|---|---|
multiprocessing.Queue | High (Pickled via OS pipe) | Highly flexible (any pickleable Python object) | Producer-Consumer pipelines |
multiprocessing.Pipe | Moderate (Two-endpoint stream) | Fast point-to-point communication | Direct duplex socket-like communication |
multiprocessing.Value / Array | Very Low (C-structs in RAM) | Restricted to primitive numeric types | Shared counters, small fixed arrays |
multiprocessing.Manager | High (RPC proxy overhead) | Extremely high (shared dicts, lists, sets) | Complex coordinating supervisor services |
shared_memory.SharedMemory | Zero (Direct memory mapping) | Raw bytes / NumPy tensors | High-throughput data science, video processing |
Multiple Choice Questions
1.
How does multiprocessing.Queue transmit Python objects between separate processes? A. By sending memory pointer addresses directly across the bus. B. By serializing objects into byte streams using pickle and transmitting them across operating system pipes. C. By writing objects to temporary JSON files on the hard drive. D. By creating a temporary HTTP web server.
multiprocessing.Queue uses background threads to pickle Python objects and stream them through OS IPC pipes to the destination process.2.
What is the primary operational advantage of Python 3.8's multiprocessing.shared_memory over standard multiprocessing.Queue for large NumPy arrays? A. It provides zero-copy access by mapping raw memory buffers directly, avoiding expensive serialization (pickling) overhead. B. It automatically backs up data to the cloud. C. It allows unpickled Python code to run on GPUs. D. It encrypts memory using AES-256.
SharedMemory allocates contiguous blocks of physical memory managed by the OS kernel, allowing multiple processes to map the buffer directly (e.g. via NumPy or memoryviews) with zero copying.3.
What occurs if a program creates a multiprocessing.shared_memory.SharedMemory block and terminates without calling .unlink()? A. Python deletes the file automatically on exit. B. An operating system-level shared memory leak occurs; the memory segment persists in the OS kernel until reboot or manual removal. C. A SyntaxError is logged. D. The process hangs indefinitely.
shm.unlink() is called, the OS continues to retain the memory block.4.
What is the difference between shm.close() and shm.unlink()? A. shm.close() deletes the memory segment, while shm.unlink() prints its size. B. shm.close() detaches the current process from the shared memory segment, while shm.unlink() instructs the operating system to destroy and deallocate the segment. C. They are identical aliases. D. shm.unlink() only works on Windows.
close() to release its local file descriptor/handle. Exactly one process (typically the creator) should call unlink() to deallocate the segment from the OS.5.
Which IPC primitive provides a fast, two-way (duplex) connection specifically between exactly two processes? A. multiprocessing.Queue B. multiprocessing.Pipe C. multiprocessing.Manager D. multiprocessing.Pool
multiprocessing.Pipe() returns a pair of connection endpoints (conn1, conn2) establishing a lightweight, bi-directional IPC channel between two endpoints.Project: Parallel File Processor
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
Related Lessons
| Previous Lesson | Next Lesson |
|---|---|
| Process vs Thread | Project: Parallel File Processor |
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.