That sentence isn't very clear. First, parent should be ancestor, as the process setting up the pipe can be a parent, or a grandparent, or a grand-grand-…-grandparent, or one of the communicating processes. Second, the sentence doesn't mean “if you want a pipe, there must exist a common ancestor process”, but “if you want a pipe, a common ancestor process must set it up”.
Under the hood, a process establishes a pipe with itself. The pipe is a file descriptor like any other, or more precisely a pair of file descriptors, one for each end. The process that created the pipe can use it immediately to send data to itself, although this is rarely useful (though a self-pipe does have its use).
A typical idiom is for a process to set up a pipe, then fork a child process, and close one end of the pipe in the parent and the other end of the pipe in the child. This lets the parent and the child process communicate in one direction. If the processes need bidirectional communication, they need two pipes (except on some unix variants where pipes are bidirectional).
The pipes are inherited in turn by any children, so the process that created the pipe may not be involved in the communication. For example, a pipe in a shell created between two external commands such as
ls | rot13 involves the following steps:
- The shell creates a pipe.
- The shell forks a process. The child closes the read end of the pipe and calls
- The shell forks a process. The child closes the write end of the pipe and calls
- The shell closes both ends of the pipe and waits for both subprocesses to exit.
If two existing processes want to communicate with each other, they can use a named pipe. (Well, there's also file descriptor passing, but it's not for the faint of heart.)