Em primeiro lugar, jobs -l
não lista processos, mas processam grupos (também conhecidos como jobs). Cada grupo de processos tem um líder de processo, cujo ID de processo (pid) é igual ao seu id de grupo de processos (pgid).
Para enviar um sinal a todos os processos em um grupo de processos, e não apenas ao seu líder, você deve chamar kill
com o negativo do pgid. Isso é descrito na manpage kill (2):
If pid is less than -1, then sig is sent to every process in the process group whose ID is -pid.
O mesmo funciona no shell:
$ sh -c 'while echo -n 1; do sleep 1; done'
111^Z
[1]+ Stopped sh -c 'while echo -n 1; do sleep 1; done'
$ jobs -l
[1]+ 11046 Stopped sh -c 'while echo -n 1; do sleep 1; done'
$ kill -CONT 11046
<nothing>
$ kill -CONT -11046
$ 11111111...
Agora, para suas conclusões:
Using kill to send CONT to the parent process gets the program running.
correto
The parent process PID is different from the one reported by jobs -l. In other words, the process I should have sent CONT signal to is different from the one I find using jobs -l.
errado, é o mesmo pid, e também é igual ao pgid.
Sending CONT to a parent process doesn't apply the same signal on the children.
correto
Using the command bg to return a process to running, sends CONT signal to the parent and all its children.
correto, mas somente se o pai e os filhos estiverem todos no mesmo grupo de processos. Além disso, ele não chama kill (2) para cada processo, basta chamá-lo uma vez com o negativo do pgid (= pid do líder do grupo de processos) e conta com o kernel para rotear o sinal para todos os processos. nesse grupo.