Reputation: 635
As I was reading APUE v3, more specifically, I found myself unable to grasp some things. First of all, let's asume that I run the following piped programs in a UNIX shell:
cat /etc/passwd | grep -i alex | awk -F : '{print $3}' | less
In the first example let's assume that I'm using a job unaware shell (sh)
The book explains that, in this situation, an eventual ps -o pid,ppid,pgid,comm would look like this (assuming the the pid of the shell is 10 and it's ppid is 5)
PID PPID PGID COMM
10 5 10 sh
11 10 10 less
12 11 10 cat /etc/passwd
13 11 10 grep -i alex
14 11 10 awk -F : '{print $3}'
In the second example let's assume we're using a job aware shell (bash):
PID PPID PGID COMM
10 5 10 bash
11 10 11 cat /etc/passwd
12 10 11 grep -i alex
13 10 11 awk -F : '{print $3}'
14 10 11 less
The question is, why in the second case, the processes are the children of the shell, and not of the last process ( as is in the first case), and presuming that shell receives a SIGCHLD for each of it's children, doesn't some kind of race condition occur between the children?
PS. Sorry for the wrong indentation. I'll try and fix it now Thanks, Alex
Upvotes: 2
Views: 65
Reputation: 17430
The question is, why in the second case, the processes are the children of the shell, and not of the last process [...]
Because that is correct behavior. Only a bug in shell can explain why less
would be a parent of the other processes in the pipe. The less
can't handle the SIGCHLD of the other processes because it hasn't started them. (What's more, that would also cause problems due to syscalls in less
failing with EINTR errors.) That would also mean that all the processes except less
would be reaped by PID 1, not the shell, since it would receive their SIGCHLD
.
Otherwise, the parent-child relation of the processes has nothing do to with the "job aware shell". Job aware shell does two things: it implements the job controls (jobs
, fg
, bg
commands) and it sets itself as a session leader (using the setsid() syscall) so that SIGHUP would be sent automatically to all child processes when it (shell) terminated.
[...] and presuming that shell receives a SIGCHLD for each of it's children, doesn't some kind of race condition occur between the children?
Race condition refers to the situation where things are executed not in the expected order. Here, there is no expected order. Most filter applications (filters like grep
: read from stdin, write to stdout) would terminate as soon as they would see EOF on stdin. It happens often that the first processes in the pipe might already terminate by the time the last process has seen any input. And that is normal. They are reaped, but their output has been already sent down the pipe and would be processed normally.
Upvotes: 1