C 杀死运行system shell命令的子进程
在父进程中,我创建了一个子进程来执行系统(“find/-print”)。 在父进程内部,当我尝试使用kill(childProcPID,SIGTERM)终止这个子进程时,它不会立即终止。系统命令继续在控制台上打印输出 下面是示例代码:C 杀死运行system shell命令的子进程,c,linux,ipc,C,Linux,Ipc,在父进程中,我创建了一个子进程来执行系统(“find/-print”)。 在父进程内部,当我尝试使用kill(childProcPID,SIGTERM)终止这个子进程时,它不会立即终止。系统命令继续在控制台上打印输出 下面是示例代码: int main(void) { pid_t childProc = fork(); switch (childProc) { case -1: perror("fork() error"); exit(E
int main(void) {
pid_t childProc = fork();
switch (childProc) {
case -1:
perror("fork() error");
exit(EXIT_FAILURE);
case 0:
system("find / -print");
printf("if I use kill(pid, SIGTERM) control doesnt reach here");
exit(EXIT_SUCCESS);
default:
;
int i = 500000;
//No a great way to put sleep
//but its just temp
while (i != 0) {
--i;
}
kill(childProc, SIGTERM);
break;
}
printf("Exit!!!!!!");
return EXIT_SUCCESS;
}
请告诉我我做错了什么,或者是杀死孩子的正确方法?首先,您应该检查从
kill()
返回的结果——如果返回0,则操作成功。但是,如果返回-1,请检查全局变量errno
,查看问题所在
如果信号发送成功,你唯一能做的就是确保你发送的是你想要的信号。正如@Till在评论中指出的,发送将更有效,因为操作系统处理前者,而目标进程不能忽略它
在任何情况下,要意识到与其他进程的交互通常是一个异步进程——无论您做什么,
kill()
返回的时间可能不会终止目标进程。系统函数本身将创建一个子进程来执行命令(然后阻止,直到该子进程终止)。您所做的是杀死调用system
的子进程,而不是杀死生成system
的子进程。尝试设置会话id并杀死进程组(man 2 kill)
这或多或少是可行的。需要注意的是,家长必须给孩子时间来设置ID(),因此需要睡眠,这是一种竞争
希望对您有所帮助。
SIGKILL
可能是一个选项。使用SIGKILL,我会得到相同的结果可能孩子甚至没有跑步。尝试使用sleep(1)
而不是您的繁忙循环。它在
中。实际上,当我运行此程序时,我看到屏幕上不断写入输出。因此,我猜系统命令仍在运行。我猜程序已经完成,您看到的只是I/O子系统的输出缓冲区清空。请尝试按CTRL-O,看看是否设置为刷新。是吗您确定该信号没有升级回父进程吗?换句话说,系统是否使用setsid()要呈现新的进程会话?但无论如何,这提示您应该使用exec
,而不是使用system
。我还觉得系统会创建自己的子线程。可能我应该使用exec系列functions@Vinit沙玛:如果你想控制是否过早终止进程,你不能使用系统
。您必须使用一个exec
函数。@Vinit Sharma:Shell命令,如cd
,将不起作用,但实际的程序会起作用。请注意,execlp
和execvp
接受文件名(因此它接受find
,而不是/usr/bin/find
)。它搜索的路径取决于你的程序的环境变量。谢谢你的帮助,但它只是编造了这个程序来显示我的问题。我知道我应该使用kill的返回值,我同意你的最后一点。是的,它确实起了作用……但我只是想知道它在任何情况下都会导致任何其他问题吗?@Vinit Sharma:没有此解决方案存在问题。我要说的是,您不应该依靠sleep
来避免争用条件,但在这种情况下,调用kill
的时间并不重要。但是,使用exec
函数不是更优雅吗?在这里,您正在创建一个新会话,以便可以将进程作为一个组杀死@Vinit Sharma。您将不会遇到任何其他问题。它只会杀死进程组中的进程。不过,您也可以随意尝试exec函数。不过,您可能会发现,根据您对它们的调用,您可能仍然需要设置ID()为了确保传播到可能产生的任何后续第三级子级。@someguy:谢谢..我在实际代码中没有使用sleep函数…它制作了这个程序,这样我就不必复制粘贴确切的代码。我也在试验exec函数。非常感谢您的输入。@maha:非常感谢您的解释。
int main(void) {
pid_t childProc = fork();
switch (childProc) {
case -1:
perror("fork() error");
exit(EXIT_FAILURE);
case 0:
setsid();
system("find / -print" );
printf("if I use kill(pid, SIGTERM) control doesnt reach here");
exit(EXIT_SUCCESS);
default:
sleep(1);
kill(childProc*-1, SIGTERM);
break;
}
printf("Exit!!!!!!");
return EXIT_SUCCESS;
}