繁体   English   中英

对于 Linux,如何使用系统调用终止 session(具有相同的 SID)中的所有进程?

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

我想弄清楚如何使用 C 的系统调用来杀死 session(具有相同的 SID)中的所有进程。我对只使用特定的 PGID 杀死所有进程不感兴趣,因为并非我感兴趣的所有进程都没有相同的 PGID,但它们具有相同的 SID。

我的研究只发现了这一点,Graeme 为脚本做了一个很好的答案: https://unix.stackexchange.com/questions/124127/kill-all-descendant-processes

我很高兴得到关于如何杀死所有直系后代孩子的答案,更高兴我如何杀死 session 中的所有孩子。

或者我问的是可能的吗? 我对那里的解决方案不感兴趣,我只是列出了父母后代的 PID。

您始终可以使用/proc/文件系统来查询进程(有关更多信息,请参阅proc(5) )。 特别是您可以扫描/proc/ PID /目录(其中PID是一些数字名称,如1234 ,它是相关的 pid,因此 pid 1234 的过程在/proc/1234/伪目录中描述;因此您可以readdir /proc/目录并找到其中的每个数字名称)并检查哪些进程具有已定义的父 pid。 您将按顺序读取伪文件,例如/proc/1234/status (及其PPid:行)。 另请参阅此答案那个答案。

请试试这个 pkill -9 -s [session id]

据我了解,您不能安全地这样做。 您唯一可以安全终止的进程是您的直接子进程,因为只有对他们,您才能确定他们的 pid 是准确的。*

对于任何其他进程,它们的非子进程的 pid 是一个移动的目标(尽管移动非常非常缓慢,除非你在一个非常繁忙的系统上,进程疯狂地产生,使得 pid 回收非常快)。

所以理论上你可以走流程树,例如:

#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 $!

但是您不能使用以上述方式获得的 pids 来实现安全的“杀死整个进程树”(session 是进程树的特定类型)。

您只能杀死 session 领导者的直接子代或它们的整个进程组,但以这种方式被杀死的进程可能不会将终止信号进一步传输到它们的子组——这是您不能安全/可靠地为它们做的事情。 以这种方式关闭 session 后剩余的进程将重新分配给 init。 如果它们停止了进程组,就没有人可以唤醒它们(这些称为孤儿组),因此 init 将向它们发送SIGCONTSIGHUP (这两个,首先发送SIGHUP )。 SIGHUP通常会杀死它们。 如果他们有SIGHUP的处理程序,他们可能会作为守护进程存在。

换句话说,如果您想安全地杀死您的 session 领导者的孩子,请阻止这些孩子创建子组(使您的 session id 始终与单个进程组 id 匹配)。


* 这样做的原因是在你成功kill你自己的子进程之后,它变成了一个僵尸,直到你wait它,并且那个僵尸保留了 pid 点,所以在你等待你的孩子之前,你孩子的pid不是一个移动的目标(所有其他 pid 都是)。

受 Basile Starynkevitch 的启发,我使用了这个简单的循环,然后我在那里等待孩子们。

/* 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);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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