简体   繁体   中英

For Linux, how can I kill all processes in a session (with same SID) using system calls?

I am trying to figure how to kill all processses in a session (with the same SID) using system calls with C. I am not interested in to just kill all with a specific PGID since not all processes I am interested about does not have the same PGID, but they have the same SID.

My research have only found this, there Graeme made an excellent answer for scripts: https://unix.stackexchange.com/questions/124127/kill-all-descendant-processes

I would be pleased to get an answer for how it would be possible to kill all direct descendant children and even more pleased how I could kill all children within the session.

Or is what I am asking possible? I am not intrested in a solution there I am simply listing the PIDs of the parents descendant.

You can always use the /proc/ file system to query processes (see proc(5) for more). In particular you can then scan the /proc/ PID / directories (where PID is some numerical name like 1234 , it is the relevant pid, so process of pid 1234 is described in /proc/1234/ pseudo-directory; hence you could readdir the /proc/ directory and find every numerical name inside it) and check which processes have a defined parent pid. You'll read sequentially pseudo-files like /proc/1234/status (and its PPid: line). See also this answer and that one .

please try this pkill -9 -s [session id]

As far as I understand, you can't do that safely. The only processes you can safely kill are your direct children because only for them you'll be able to know with certainty that their pid is accurate.*

For any other process, pids of their nonchildren processes are a moving target (though very very slowly moving, unless you're on an extremely busy system where processes are spawned like crazy, making pid recycling very fast).

So you could theoretically walk the process tree, eg:

#This will create a nice process tree
(sleep 1000 & ( sleep 1000&  sleep 1000& sleep 1000)&  sleep 1000 )&
#View it with 
ps T --forest
#Or recursively get all the nodes (this should match the corresponding part of the above ps command)
walk_processes() { echo $1; cat /proc/$1/task/$1/children | while read -d ' ' pid; do walk_processes $pid; done;  }
walk_processes $!

But you can't use the pids obtained in the above fashion to implement a safe "kill a whole process tree" (with a session being a specific type of a process tree).

You can only kill the direct children of the session leader or their whole process groups, but the processes that get killed in this fashion may not transmit the kill signal further on to their subgroups—something you can't safely/reliably do for them. The processes that remained after a closing of a session in this way are then reparented to init. If they're stopped process groups, they'd have no one to wake them up (these are called orphaned groups), so init will send them SIGCONT and SIGHUP (these two, with SIGHUP being sent first). SIGHUP will normally kill them. If they have a handler for SIGHUP , they may live on as daemons.

In other words, if you want to safely kill children of your session leader, prevent those children from creating subgroups, (making your session id always match with a single process group id).


*The reason for that is after you successfully kill your own child process, it becomes a zombie until you wait on it, and that zombie reserves the pid spot so until you've waited on your child, your child's pid is not a moving target (all other pids are).

With inspiration from Basile Starynkevitch I used this simple loop, there I afterwards waits for the children.

/* Searches through all directories in /proc */
while((dent = readdir(srcdir)) != NULL) {
    /* If numerical */
    if (dent->d_name[0] >= '0' && dent->d_name[0] <= '9') {
        /* Take data from /proc/[pid]/stat, see URL below for more info */
        /* http://man7.org/linux/man-pages/man5/proc.5.html */
        sprintf(path, "/proc/%s/stat", dent->d_name);
        stat_f = fopen(path,"r");
        fscanf(stat_f, "%d %*s %*c %d", &pid, &ppid);
        fclose(stat_f);
        /* Kill if shell is parent to process */
        if (shell_pid == ppid) kill(pid, SIGKILL);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM