C 杀死运行system shell命令的子进程

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

在父进程中,我创建了一个子进程来执行系统(“find/-print”)。 在父进程内部,当我尝试使用kill(childProcPID,SIGTERM)终止这个子进程时,它不会立即终止。系统命令继续在控制台上打印输出

下面是示例代码:

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;
}