ipc · medium
IPC: Pipes & FIFOs — Unidirectional Byte Streams Between Processes
POSIX pipes are kernel-managed unidirectional byte streams. pipe() returns two fds: fd[0] (read end) and fd[1] (write end). After fork(), both parent and child inherit both ends; each closes the unused end. write() into fd[1] copies bytes into the kernel buffer (~65KB); read() from fd[0] drains them. Both operations block if the buffer is full or empty respectively — this provides built-in flow control. Closing the write end sends EOF to the reader (read() returns 0). Anonymous pipes are visible only to related processes. Named FIFOs (mkfifo) create a filesystem entry visible to any process on the same host; open() on a FIFO blocks until both ends connect. Shell | (pipe operator) creates an anonymous pipe between adjacent processes in the pipeline.
pipe(): fd[0]=read, fd[1]=write — unidirectional byte stream; always close unused end after fork; write blocks when full, read blocks when empty; close(write end) sends EOF; named FIFO (mkfifo) extends this to unrelated processes via a filesystem path.
The code
// Anonymous pipe: parent → child byte streamint fd[2];pipe(fd); // fd[0]=read end, fd[1]=write end
pid_t child = fork();if (child == 0) { close(fd[1]); // child doesn't write char buf[256]; ssize_t n = read(fd[0], buf, sizeof(buf)); buf[n] = '\0'; printf("Child got: %s\n", buf); close(fd[0]);} else { close(fd[0]); // parent doesn't read const char* msg = "Hello from parent"; write(fd[1], msg, strlen(msg)); close(fd[1]); // EOF → child's read() returns 0 wait(nullptr);}
// Named FIFO — any two unrelated processesmkfifo("/tmp/my.fifo", 0644);// Writer (one process): open O_WRONLY, write, close// Reader (other process): open O_RDONLY, read, close// Both open() block until the other end connects!// unlink() removes the FIFO from the filesystem.
// Shell pipe is a kernel anonymous pipe:// ls -la | grep .cpp// stdout of ls → pipe → stdin of grepWhat this lesson walks through
- 01Pipe fundamentals — unidirectional kernel byte stream
- 02fork() — child inherits both pipe ends
- 03Parent writes — bytes flow into kernel buffer
- 04Parent closes write end — child reads EOF
- 05Pipe full — writer blocks
- 06Named FIFO vs anonymous pipe — when to use which
pipe(fd) creates two file descriptors: fd[0] (read end) and fd[1] (write end). Data flows one way only: write to fd[1], read from fd[0]. The kernel maintains an in-memory ring buffer (~65KB). Pipes are anonymous — only visible via inherited file descriptors after fork().
See it animated — step by step, at your own pace
Unlock the full interactive walkthrough of IPC: Pipes & FIFOs — Unidirectional Byte Streams Between Processes and 100+ animated C++ interview lessons.