Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 对于Linux,如何使用系统调用终止会话(具有相同SID)中的所有进程?_C_Linux_System Calls_Kill_Sessionid - Fatal编程技术网

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

C 对于Linux,如何使用系统调用终止会话(具有相同SID)中的所有进程?,c,linux,system-calls,kill,sessionid,C,Linux,System Calls,Kill,Sessionid,我试图找出如何使用C的系统调用来终止会话中的所有进程(具有相同的SID)。我不想只终止具有特定PGID的所有进程,因为我感兴趣的并非所有进程都不具有相同的PGID,但它们具有相同的SID 我的研究只发现了这一点,Graeme对脚本给出了一个极好的答案: 我很高兴能得到一个答案,说明如何能够杀死所有直系后代儿童,更高兴的是,我如何能够在治疗过程中杀死所有儿童 或者我所要求的是可能的?我对这里的解决方案不感兴趣,我只是列出父代后代的PID。您可以始终使用/proc/文件系统来查询进程(有关更多信息

我试图找出如何使用C的系统调用来终止会话中的所有进程(具有相同的SID)。我不想只终止具有特定PGID的所有进程,因为我感兴趣的并非所有进程都不具有相同的PGID,但它们具有相同的SID

我的研究只发现了这一点,Graeme对脚本给出了一个极好的答案:

我很高兴能得到一个答案,说明如何能够杀死所有直系后代儿童,更高兴的是,我如何能够在治疗过程中杀死所有儿童


或者我所要求的是可能的?我对这里的解决方案不感兴趣,我只是列出父代后代的PID。

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

据我所知,这样做是不安全的。 您可以安全地杀死的唯一进程是您的直接子进程,因为只有对它们,您才能确定它们的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 $!
但您不能使用以上述方式获得的PID来实现安全的“杀死整个流程树”(会话是流程树的特定类型)

您只能终止会话负责人或其整个进程组的直接子进程,但以这种方式终止的进程可能无法将终止信号进一步传输到它们的子组,这是您无法安全/可靠地为它们执行的操作。然后,以这种方式结束会话后剩余的进程将重新租给它们init。如果它们是被停止的进程组,则没有人来唤醒它们(这些被称为孤立组),因此init将向它们发送
SIGCONT
SIGHUP
(这两个组,首先发送
SIGHUP
).
SIGHUP
通常会杀死它们。如果它们有一个用于
SIGHUP
的处理程序,则它们可能作为守护进程存在

换句话说,如果您想安全地杀死会话负责人的子级,请阻止这些子级创建子组(使会话id始终与单个进程组id匹配)



*原因是在您成功地
杀死您自己的子进程后,它会变成一个僵尸,直到您
等待它,而僵尸会保留pid点,因此直到您等待您的孩子,您孩子的
pid
不是一个移动目标(所有其他pid都是).

受巴兹尔·斯塔林克维奇的启发,我使用了这个简单的循环,然后在那里等待孩子们

/* 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);
    }
}
/*搜索/proc中的所有目录*/
而((dent=readdir(srcdir))!=NULL){
/*如果是数字*/
if(dent->d_name[0]>='0'&&dent->d_name[0]d_name);
stat_f=fopen(路径“r”);
fscanf(stat_f,“%d%*s%*c%d”、&pid和&ppid);
fclose(stat_f);
/*如果shell是进程的父级,则终止*/
if(shell_pid==ppid)kill(pid,SIGKILL);
}
}

在linux上没有固有的选项可以杀死具有相同SID的进程,您唯一的选项是在最后一句话中。@否:我想这就是为什么我的研究没有发现我的任何东西……好的,但是有可能杀死所有直接子进程(都具有相同的PPID)吗以某种方式?仅当它们属于同一个pgrp时。您可以1.杀死特定的pid。2.杀死进程组中的所有进程。3.杀死您有权杀死的所有进程(除非您是root用户,否则杀死您自己用户的所有进程)。4.让子进程在父进程死亡时杀死自己(仅当您可以更改所有相关流程的源代码时才相关)