Memory ordering, futex-backed locks và IPC trade-offs
Shared memory minimizes copy but moves correctness into synchronization; message-based IPC adds kernel/protocol boundaries and backpressure semantics.
Sync & IPC
Atomicity and ordering
Compiler/CPU reorder absent synchronization; data race makes higher-level language behavior unsafe/undefined by its model. Atomics provide operations/order constraints, not multi-variable invariant automatically. Cache coherence is not language-level happens-before.
Mutex/condition/futex
Uncontended mutex may stay user-space atomic; futex lets threads sleep/wake in kernel on contention. Condition variables require predicate loop because spurious wakeups/state changes. Robust mutex, priority inversion and owner death need domain policy.
Deadlock/livelock/starvation
Deadlock cycle of waits; prevent lock ordering, scope and avoiding external calls under lock. Livelock changes state without progress; starvation unfair scheduling/locks. Timeouts only bound wait, can leave partial state and hide root cause.
Pipes and sockets
Pipes byte streams with bounded buffers/EOF when writers close; Unix sockets support bidirectional/credentials/FD passing; TCP crosses network and adds framing/retry/security. Short reads/writes and backpressure always handled.
Shared memory/mmap
Very low-copy communication but needs layout/versioning, atomics/locks, crash recovery and lifecycle/unlink. Process crash does not rollback shared state. Ring buffers require careful producer/consumer ordering and wrap semantics.
Queues and signals
POSIX/System V queues add message boundaries/limits; eventfd/signalfd integrate notifications into event loops; signals carry little data and coalesce. Choose by throughput, isolation, ordering, durability, security and operational visibility.