Compare
Side-by-side on the decisions that recur: process vs thread, threads vs async, mutex vs semaphore, blocking vs non-blocking I/O, container vs VM — with when to choose each.
Process vs ThreadThreads vs Async / event loopConcurrency vs ParallelismMutex vs SemaphoreBlocking I/O vs Non-blocking / async I/Oselect / poll vs epoll / kqueueContainer vs Virtual machineStack vs HeapPipe vs Shared memoryOS page cache vs Application cache
| Pipe | Shared memory | |
|---|---|---|
| Data path | Copy into a kernel buffer, copy out on the other side (two copies, two syscalls) | Both processes map the same frames — zero copies after setup |
| Synchronisation | Built in: the writer blocks when full, the reader blocks when empty, EOF on close | None: you bring a semaphore, futex, or lock-free ring buffer |
| Throughput | Hundreds of MB/s to a few GB/s, bounded by copies and the 64 KB buffer (Linux default) | Memory bandwidth; GB/s to tens of GB/s |
| Semantics | A byte stream (or a message queue with mkfifo/named pipes); one direction per pipe | Raw bytes with whatever structure you impose; any direction |
| Setup | pipe() before fork, or a named pipe (FIFO; Windows named pipes are message-capable) | shm_open + mmap / memfd, System V shmget, Windows CreateFileMapping |
| Failure mode | Deadlock when both sides fill their pipes; SIGPIPE when the reader dies | Corruption from a missing lock; a crashed peer leaves a half-written structure |
| Choose this when | Simple producer-consumer between two processes, shell-style streaming, or when you want the kernel to do the flow control. | High-volume or latency-critical exchange (database buffer pools, media pipelines, IPC between engines) and you can own the synchronisation. |