爱国者
爱国者

Reputation: 4328

Why child process still alive after parent process was killed in Linux?

Someone told me that when you killed a parent process in linux, the child would die.
But I doubt it. So I wrote two bash scripts, where father.shwould invoke child.sh

Here is my script:

enter image description here

Now I run bash father.sh, you could check it ps -alf enter image description here

Then I killed the father.sh by kill -9 24588, and I guessed the child process should be terminated but unfortunately I was wrong. enter image description here

Could anyone explain why?

thx

Upvotes: 36

Views: 53685

Answers (4)

Beracah
Beracah

Reputation: 362

Generally killing the parent also kills the child.

The reason that you are seeing the child still alive after killing the father is because the child only will die after it "chooses" (the kernel chooses) to handle the SIGKILL event. It doesn't have to handle it right away. Your script is running a sleep() command (i.e. in the kernel), which will not wake up to handle any events whatsoever until the sleep is completed.

Why is PPID #1? The parent has died and is no longer in the process table. child.sh isn't linked inexplicably to init now. It simply has no running parent. Saying it is linked to init creates the impression that if we somehow leave init, that init has control over shutting down the process. It also creates the impression that killing a parent will make the grandparent the owner of a child. Both are not true. That child process still exists in the process table and is running, but no new events based upon it's process ID will be handled until it handles SIGKILL. Which means that the child is a pre-zombie, walking dead, in danger of being labeled .

Killing in the process group is different, and is used to kill the siblings, and the parent by the process group #. It's probably also important to note that "killing a process" is not "killing" per se, in the human way, where you expect the process to be destroyed and all memory returned as though it never was. It just sends a particular event, among many, to the process for it to handle. If the process does not handle it properly, then after a while the OS will come along and "clean it up" forcibly.

It (killing) doesn't happen right away because the child (or even the parent) could have written something to disk and be waiting for I/O to complete or doing some other critical task that could compromise system stability or file integrity.

Upvotes: -3

fge
fge

Reputation: 121702

No, when you kill a process alone, it will not kill the children.

You have to send the signal to the process group if you want all processes for a given group to receive the signal

For example, if your parent process id has the code 1234, you will have to specify the parentpid adding the symbol minus followed by your parent process id:

kill -9 -1234

Otherwise, orphans will be linked to init, as shown by your third screenshot (PPID of the child has become 1).

Upvotes: 57

Muthu
Muthu

Reputation: 29

pkill -TERM -P <ProcessID>

This will kill both Parent as well as child

Upvotes: 2

charz
charz

Reputation: 77

-bash: kill: (-123) - No such process

In an interactive Terminal.app session the foreground process group id number and background process group id number are different by design when job control/monitor mode is enabled. In other words, if you background a command in a job-control enabled Terminal.app session, the $! pid of the backgrounded process is in fact a new process group id number (pgid).

In a script having no job control enabled, however, this may not be the case! The pid of the backgrounded process may not be a new pgid but a normal pid! And this is, what causes the error message -bash: kill: (-123) - No such process, trying to kill a process group but only specifying a normal pid (instead of a pgid) to the kill command.

# the following code works in Terminal.app because $! == $pgid
{
sleep 100 &
IFS=" " read -r pgid <<EOF
$(ps -p $! -o pgid=)
EOF
echo $$ $! $pgid
sleep 10
kill -HUP -- -$!
#kill -HUP --  -${pgid}  # use in script
}

Upvotes: 6

Related Questions