无法杀死以spawn开始的PID

时间:2017-04-19 13:17:51

标签: c linux

前几天,我问here如何在不使用fork()的情况下使用C启动程序。这个解决方案工作正常.....除了我不能杀死这个子进程! 我的程序(在这种情况下,'rbfeeder')有一些线程....当我发送kill信号时,只有线程被杀死(我认为)。我做错了什么?

这是用于“启动”rbfeeder的代码:

\DB::enableQueryLog();
\DB::getQueryLog();

这是“停止”的代码:

/*
 * Start dump1090, if not running
 */
void startDump(void) {

    if (p_dump != 0) {
        log_level(8, "Looks like dump is already running.\n");
        return;
    }

    pid_t ret = run_cmd("/home/jmaurin/dev/client/rbfeeder");

    if (ret != 0) {
        log_level(8, "Ok, started! Pid is: %i\n", ret);
        p_dump = ret;
        sendStats();
    } else {
        log_level(8, "Error starting dump1090\n");
        p_dump = 0;
        sendStats();
    }

    return;
}

和run_cmd函数:

void stopDump(void) {

    if (checkDumpRunning()) {
        log_level(3, "Dump is running, let's try to kill.\n");

        if (kill(p_dump, SIGKILL) == 0) {
            log_level(3,"Succesfull kill dump!\n");
            sendStats();
            return;
        } else {
            log_level(3,"Error killing dump.\n");
            return;
        }


    } else {
        log_level(3, "Dump is not running.\n");
    }

    return;
}

p_dump是一个保存PID的全局变量。

此图像是我的“客户端”收到命令(通过以太网)启动外部程序时:

enter image description here

然后,在同一台机器上的HTOP ....看到PID是相同的,这意味着我的变量是正确的:

enter image description here

然后,我发送了一个'stop'命令,我的客户端执行'stopDump',但是一个进程仍在运行(来自同一程序的其他线程被'杀死'):

enter image description here

外部程序本身并不“生成/派生”,但它确实有线程。

2 个答案:

答案 0 :(得分:3)

你的杀戮成功完成,因为这个过程正在变成一个僵尸,(HTOP中状态栏中的Z)。僵尸是一个仍然在内核中有元数据的进程,但实际上并没有运行。为了摆脱僵尸,父母必须等待这个过程。由于您的进程是父进程,因此在kill成功后添加对waitpid(p_dump)的调用应处理此问题。

答案 1 :(得分:0)

user1937198的答案运行良好,但我找到了另一种不需要调用任何功能的方式,例如' waitpid'。

struct sigaction sigchld_action = {
  .sa_handler = SIG_DFL,
  .sa_flags = SA_NOCLDWAIT
};
sigaction(SIGCHLD, &sigchld_action, NULL);

至少在我的情况下,它会在杀死后阻止僵尸进程。它工作正常。