On this page
Pipes and socketpair
Coverage: pipe → socketpair (AF_UNIX) → splice → pipe capacity → AF_UNIX vs TCP → Performance considerations Applicable to: Linux userspace IPC
Overview
Pipes and Unix domain sockets are the most commonly used local IPC mechanisms on Linux. Pipes are suitable for unidirectional data streams (parent-child processes), while socketpairs are suitable for bidirectional communication. Understanding the differences in their kernel implementations (pipes are based on pipefs, while Unix sockets are based on VFS + an independent protocol stack) is important for choosing the correct IPC mechanism.
pipe: Unidirectional Pipe
int pipefd;
; // pipefd[0]=read end, pipefd[1]=write end
// Or: pipe2(pipefd, O_NONBLOCK | O_CLOEXEC);
; // Write
; // Read
// Default pipe capacity: 16 pages (64KB on 4KB pages)
// Adjustable: fcntl(fd, F_SETPIPE_SZ, size)
Inside pipe
// fs/pipe.c
// Each pipe = one pipe_inode_info:
// Ring buffer (16 pages default)
// Readers waiting for data → placed in wait queue → when writer arrives → wake up
// Writers waiting for space → placed in wait queue → when reader arrives → wake up
// Pipe capacity:
cat /proc/sys/fs/pipe-max-size # Maximum
splice: Zero-copy Transfer
// splice is the superpower of pipes:
// Bypasses userspace → FD1 → pipe → FD2
// File → socket (underlying mechanism of sendfile):
; // File → pipe
; // Pipe → socket
// → Zero-copy: Data goes directly from page cache to socket buffer
socketpair: Bidirectional Pipe
int sv;
;
// sv[0] ↔ sv[1] for bidirectional communication
;
; // Receives "hello"
// SOCK_STREAM: Reliable, ordered, bidirectional (similar to TCP)
// SOCK_DGRAM: Unreliable, preserves message boundaries (similar to UDP)
// SOCK_SEQPACKET: Reliable + preserves message boundaries (5.3+)
AF_UNIX Socket vs TCP
Local process-to-process communication on the same machine:
AF_UNIX socket (Unix domain):
Does not traverse the protocol stack → only passes sk_buff within the kernel
Latency: ~2μs (vs TCP localhost ~10μs)
Throughput: ~5GB/s (vs TCP localhost ~2GB/s)
Why is AF_UNIX fast?
1. No TCP state machine (no SYN/SYN-ACK/FIN)
2. No checksum (not needed for local communication)
3. No flow control/congestion control
4. No IP fragmentation/reassembly
AF_UNIX Credential Passing (SCM_CREDENTIALS):
sendmsg(sock, msg, 0) ← Passes pid/uid/gid along
Receiver: recvmsg → SCM_CREDENTIALS → Trusts sender identity
→ DBus, systemd, polkit all rely on this
pipe vs socketpair vs eventfd
| pipe | socketpair (AF_UNIX) | eventfd | |
|---|---|---|---|
| Direction | Unidirectional | Bidirectional | Unidirectional signal |
| Data | Byte stream | Byte stream / Message | 8-byte counter |
| Capacity | 64KB+ | Send buffer (default 200KB) | 1 counter |
| splice | Supported | Not supported (partially supported in 4.x+) | Not supported |
| Credential Passing | No | Yes (SCM_CREDENTIALS) | No |
| epoll | Supported | Supported | Supported |
References
- man: pipe(2), socketpair(2), splice(2), unix(7)
- Source Code:
fs/pipe.c,net/unix/af_unix.c
Keywords: pipe, socketpair, AF_UNIX, splice, SCM_CREDENTIALS, pipe capacity, eventfd