[1] 2349 Running fred &
[2] - 2367 Running bob &
[3] + 2382 Running dave | george &
How does all this work? Every time you run a job, the process(es) in the
job are put into a new process group. Each process
in a process group, besides its unique process ID number, also has
a process group ID. The process group ID is the
same as the process ID of the process group leader,
which is one of the processes invoked as part of the job. (The last one in
the pipeline, in fact.) The numbers that the shell prints are actually
the process group IDs. (Note that for job 3, there are two processes,
but only one number.)
Now, your terminal device, be it a real serial port or a pseudo-terminal such as
you get in a windowing system or telnet session, also has
a process group ID number.
Processes whose process group ID matches that of the terminal "own"
the terminal, in the sense that they are allowed to read input from it.
In brief, job control works by setting the process group of the terminal to be
the same as the process group of the current job.
(There are lots more technical details, including the idea of a "session"
introduced by POSIX, but those details aren't necessary for understanding the
day-to-day use of job control.)