💾 Archived View for yujiri.xyz › software › guide › ipc.gmi captured on 2024-06-16 at 12:38:32. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2024-02-05)
-=-=-=-=-=-=-
Learn programming for good instead of profit
There are a few different ways processes can communicate with each other. The most important two are pipes and sockets.
The Ubuntu command-line tutorial introduced the concept of pipes from a command-line perspective (along with other shell redirection features).
From a kernel/programming perspective, a pipe is basically a pair of file descriptors (one read-only and the other write-only) that, instead of a file on your disk, refer to a buffer of memory inside the kernel. When you write to the write end of the pipe, the kernel makes that written data available to be read from the other end.
Pipes are created with a syscall named `pipe`. Now you can get a more detailed view of what the shell does when you type a command like `ls | wc`. First it calls `pipe`, then it spawns `ls` with the write end of the pipe as its stdout, and spawns `wc` with the read end of the pipe as its stdin.
A socket is a versatile thing that represents some sort of remote end that a process can communicate with in both directions. The other end might be another process on your computer, or it could be another computer on the internet! Sockets are how network programming is done.
There are different kinds of sockets, but the most common is a stream socket, which is pretty similar to a pipe. The main difference is that a socket is bi-directional: each end can write data that the other end will read. (You can think of it as two pipes tied together which flow in opposite directions.)
When a socket represents another network address, it's called a network socket. There are two ways to get a socket that's connected to another process on your own computer instead of a network socket:
If you're on Linux right now, you probably have some Unix domain sockets in `/run` or some of the folders within it. Their names often end in `.sock`.
I mention these for completeness even though I've never actually seen them used. A fifo is a thing that exists on Unix that's like a pipe (it's one-directional) except that it exists in the filesystem, like a Unix domain socket.
There are syscalls for setting up a region of memory that multiple processes can access directly. Honestly I can't teach much about shared memory because I've never used it in any of my work, but I know it is used in important parts of the Linux world, such as Wayland.
The advantage of shared memory over pipes and sockets is performance: since a block of shared memory is actually part of your process's address space, you can access it without the overhead of a syscall.
The disadvanages are safety (two processes accessing the same data at the same time can lead to crazy bugs unless you synchronize them properly) and that it's less straightforward to use for the common task of simply transferring a stream of data from one process to another.