Killing all child processes linux

C/C++ program to kill all child processes of a parent process in UNIX?

Now I want to write the definition of the above function, which will 1st get all the child processes and then kill them. Is there any API in Unix which will take parent PID and will return the number of child processes created by the parent process?

@BrettHale it’s useful indeed, but parent-child relationship is quite different than process group relationship.

Will kill(ParentPID, SIGKILL), kill all the child processes of any parent process? The defination of SIKILL is as below. SIGKILL — The most powerful termination signal,which ends a process immediately and cannot be blocked or handled by a program.

@user3253461 The choice of signal is unrelated to the choice of process. KILL kills a process and cannot be handled or blocked, but you’re still killing that process, not any other process.

2 Answers 2

There is no standard Unix API to retrieve the list of child processes of a given process.

You can list all the processes on the system with their parent process, and build the process tree from that. The portable way to do this is to run the command

and parse the output ( popen followed by a loop of scanf(«%ld %ld\n») will do). Store the data as a finite map from PPID to PID, then walk the tree to collect the list of descendants of the process you’re interested in.

If any of the processes concerned forks or exits during your processing, you may miss it. If you’re unlucky, a process may exit and its PID may get reused while you’re doing all this. Also, if process P forks a child process Q which forks a grandchild R, and then Q exits, R’s PPID will be set to 1, so you won’t detect that R was originally a descendant of P.

In a nutshell: whatever your problem is, this is very probably the wrong approach.

Unix has a feature to deal with this: process groups. There’s a good chance that process groups are the answer to the problem you’re trying to solve. You can atomically send signal signal_number to all the processes in a process group with kill(-pgid, signal_number) .

You should arrange for all the processes you want to kill to belong to the same process group, and for the processes you don’t want to kill not to belong to that process group. Make the parent process call setsid or setpgid , then kill the process group.

Источник

How do you kill all child processes without killing the parent

I have a script which runs a background process at the beginning, then towards the end needs to stop that background process and its children, THEN do some other tasks etc then return an error code if necessary. How do I do this? I have seen several examples of how to kill the whole tree including the parent process (eg kill 0 ) but I want the main script to continue running and return the right error code. E.g.:

./some_process_with_child_processes & ./do_stuff kill $! # doesnt kill child processes! ./do_other_stuff exit 5 

Couple of immediate thoughts come to mind, without knowing anything about your code base, you could make sure that all of the child processes have a unique name related to the parent process, eg, everything is prefixed with foo_project_child_, that way you can simply use pkill -f foo_project_child_, to handle things, otherwise, are you opposed to using a data store like redis etc which you can query and figure out which processes you need to kill ?

Читайте также:  Ролевое управление доступом astra linux

I’d rather not do a global pkill on all foo_project_etc* instances if possible, i want this to be self-contained. i haven’t looked into redis, i will now. @Ed How do I modify my shell script to not be killed but its child processes will be? That is my question.

2 Answers 2

To expand on Ed Heal’s comment:

In the parent process, trap SIGTERM, eg

trap «echo received sigterm» SIGTERM

Then, when you want to terminate all the child processes, in the main script do

The parent will also receive SIGTERM, but that doesn’t matter, since it’s trapped that signal.

You may also find it useful to set a trap for EXIT in the child processes so they can clean up when they receive SIGTERM.

You could send the child processes SIGKILL, but that’s a bit brutal, and the child processes won’t have a chance to do any clean up.

Here are some scripts that illustrate how a parent script can kill its children individually, rather than en masse using kill -s SIGTERM 0 .

#!/bin/bash # trap test # Written by PM 2Ring 2014.10.23 myname=$(basename "$0") child=sleeploop delay=$ loops=$ sig=SIGTERM # sig=SIGKILL # sig=SIGINT # killed=False signal_children() < killed=True for ipid in "$" do echo "Sending $sig to $ipid" kill -s $sig $ipid done > set_INT_trap() < msg="echo -e \"\n$myname received ^C, sending $sig to children\"" trap "$msg; signal_children" SIGINT >trap "echo \"bye from $myname\"" EXIT pids=() for i in A B C;do echo "running $child $i $delay . " ./$child $i $delay & pid=$! # echo -e "$child$i PID = $pid\n" pids+=($pid) done # echo "all child PIDs: $" echo "$myname PID = $$" echo; ps; echo set_INT_trap $sig trap "echo $myname Received SIGTERM; signal_children" SIGTERM echo "$myname sleeping. " sleep 18 & wait $! echo "$myname awake" [[ $killed != True ]] && < echo "$myname sending $sig"; signal_children; >echo "$myname finished" 
#!/bin/bash # child script for traptest # Written by PM 2Ring 2014.10.23 myname="$(basename "$0")$1" delay=$2 loops=$ set_trap() < sig=$1 trap "echo -e '\n$myname received $sig signal';exit 0" $sig >trap "echo \"bye from $myname\"" EXIT set_trap SIGTERM # set_trap SIGINT #Select sleep mode if false then echo "$myname using foreground sleep" Sleep() < sleep $delay >else echo "$myname using background sleep" Sleep() < sleep "$delay" & wait $! >fi #Time to snooze :) for ((i=0; i 

This even works if you want to pipe the output of traptest , eg try

Источник

How do you kill a process tree in linux? [closed]

Sometimes, sending a SIGTERM to a process will cause it to send SIGTERM to all its child processes. However, sometimes this doesn't work. Is there a command or a utility that will allow me to kill a process and all its child processes at the same time? I usually resort to manually collecting all the pids into one kill command, but it feels stupid. This SO question asks how to do this with perl, but anything that gets the job done would be great.

@Andrew - It's not for "whatever reason". It's because 'kill' is not really named correctly. What it does is send a signal to the process. The signal it sends by default is TERM, which by default will terminate the process. But, the process can 'catch' it so it can do cleanup work before it exits. The -9 causes it to send the KILL signal, which terminates the process immediately. You want to avoid doing this if possible. Only use -9 if a regular kill didn't work in the first few seconds.

4 Answers 4

Assuming that the processes share a session identifier (which they should unless they've explicitly called setsid(), you can kill them by session using pkill:

user@machine:~> ps -o pid,sess,cmd -U user PID SESS CMD 12804 12804 -bash 12916 12804 ps -o pid,sess,cmd -U user user@machine:~> sh sh-3.00$ sh sh-3.00$ sh sh-3.00$ sh sh-3.00$ sh sh-3.00$ sh sh-3.00$ ps -o pid,sess,cmd -U user PID SESS CMD 12804 12804 -bash 12920 12804 sh 12921 12804 sh 12922 12804 sh 12924 12804 sh 12926 12804 sh 12928 12804 sh 12937 12804 ps -o pid,sess,cmd -U user sh-3.00$ 

If from another terminal I do:

Then everything dies in one fell swoop.

You can similarly kill by process group, though this tends to be more useful for many children that are all one level below a parent, not a chain of associated processes.

Usually, a responding client should receive a sigterm and off itself, thereby terminating all its forked child processes. If, on the other hand, the client is not responding, a normal termination signal will probably evoke no response.

So you then proceed to send a SIGKILL, which tells the system itself to Make That Process Stop, Now - which it can do most of the times, except when the process is in a state of ininterruptible sleep, like waiting for some I/O input or similar.

In that case, even the SIGKILL will end up doing nothing to the process; the child process will probably in a similar state of retardation.

There is a border case where the parent process might terminate just nicely, but the child process is not killable. Then you will end up with a zombie process that cannot be cleaned up since its father is gone, but it is not responding to anything. The only way to get rid of those is a reboot; in most cases, though, they are quite harmless, as the only thing they do is take up a PID while whatever socket they tried to use has withered away already.

Источник

linux - [Solved-5 Solutions] Best way to kill all child processes in Linux - ubuntu - red hat - debian - linux server - linux pc

What is the best way to kill all child processes in Linux ?

Linux - Solution 1:

If you need to kill is a single process group. (This is often the case if the tree is the result of forking from a server start or a shell command line.) You can discover process groups using GNU ps as follows:

click below button to copy the code. By - Linux tutorial - team

If it is a process group you want to kill, just use the kill(1) command but instead of giving it a process number, give it the negation of the group number. For example to kill every process in group 5112, use kill -TERM -- -5112.

Linux - Solution 2:

click below button to copy the code. By - Linux tutorial - team

This will kill all processes that have the parent process ID 27888.

 CPIDS=$(pgrep -P 27888); (sleep 33 && kill -KILL $CPIDS &); kill -TERM $CPIDS
click below button to copy the code. By - Linux tutorial - team

which schedule killing 33 second later and politely ask processes to terminate.

Linux - Solution 3:

To kill a process tree recursively, use killtree():

 #!/bin/bash killtree() < local _pid=$1 local _sig=$kill -stop $ # needed to stop quickly forking parent from producing children between child killing and parent killing for _child in $(ps -o pid --no-headers --ppid $); do killtree $ $ done kill -$ $ > if [ $# -eq 0 -o $# -gt 2 ]; then echo "Usage: $(basename $0) [signal]" exit 1 fi killtree $@
click below button to copy the code. By - Linux tutorial - team

Linux - Solution 4:

 for child in $(ps -o pid -ax --ppid $PPID) do . done
click below button to copy the code. By - Linux tutorial - team

Linux - Solution 5:

 for child in $(ps -o pid,ppid -ax | \ awk "< if ( \$2 == $pid ) < print \$1 >>") do echo "Killing child process $child because ppid = $pid" kill $child done
click below button to copy the code. By - Linux tutorial - team

linux red hat debian opensuse ubuntu arch linux mandrake get link linux computer linux pc linux server linux desktop learn linux red hat linux red hat enterprise linux linux software linux tutorial linux operating system suse linux linux download linux os linux ubuntu vmware linux lunix linux windows linux news linux usb linux commands unix linux linux version what is linux linux centos linux ftp terminate child process when parent killed get process group id bash get process group id what happens to child process when parent is killed bash process group bash terminate child process when parent killed linux process group send sigterm to child process

    INTERVIEW TIPS
  • Final Year Projects
  • HR Interview Q&A
  • GD Interview
  • Resume Samples
  • Engineering
  • Aptitude
  • Reasoning
  • Company Questions
  • Country wise visa
  • Interview Dress Code CAREER GUIDANCE
  • Entrance Exam
  • Colleges
  • Admission Alerts
  • ScholarShip
  • Education Loans
  • Letters
  • Learn Languages

World's No 1 Animated self learning Website with Informative tutorials explaining the code and the choices behind it all.

Источник

Оцените статью
Adblock
detector