我如何知道进程何时被终止

我如何知道进程何时被终止

以下代码启动一个冗长的 nmap 进程,然后主程序尝试终止它。我从 shell 运行它,并且还在另一个窗口中运行 GTOP,只是为了看看是否一切都成功。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include <sys/wait.h>

int main()
{
int ret,childpid=0;
ret = fork();
if (ret == 0)
   {
   printf("Here A %d.. \n", ret);
   char *params[5]  = {"nmap","-sS","-A","192.168.0.1/24",0}; //cmd params filled
   childpid = execv( "/usr/bin/nmap" , params);  //parameters for cmd
   printf("\n child exiting (%d) (%d).. \n", childpid,errno); //on successful execution of cmd, this exit never appears
   }
else
   {
   childpid=ret;  
   printf("parent exiting\n");
   if (childpid!=0)
      { 
      printf("child %d about to be killed wait 15 so that htop has time to see it\n",childpid);
      sleep(15);
      kill(childpid, SIGTERM);  
      sleep(2);
      kill(childpid, SIGKILL);
      printf("killed wait 15 HTOP should have time to update\n");
      sleep(15);
      }
   }
return 1;
}

HTOP 看到 nmap 正在启动,但是当我终止该进程时,它仍然显示在 HTOP 显示中。当我的主程序退出时,HTOP 将从进程列表中删除 nmap。我做错了什么或者误解了 HTOP 吗?

答案1

您生成了一个子进程,将其杀死,但没有继续wait(2)执行。该进程现在是一个僵尸进程,为它的父进程徘徊。当父进程死亡时,僵尸进程就成为孤儿进程,由 init 来处理。从man 2 wait在 Linux 上:

在子进程终止的情况下,执行等待允许系统释放与子进程相关的资源;如果不执行等待,则终止的子进程仍处于“僵尸”状态(请参阅下面的注释)。

并从注释中:

终止但尚未等待的子进程将成为“僵尸”。内核维护有关僵尸进程的最小信息集(PID、终止状态、资源使用信息),以便允许父进程稍后执行等待以获得有关子进程的信息。只要僵尸进程没有通过等待从系统中移除,它就会消耗内核进程表中的一个槽,如果该表已满,则无法创建更多进程。如果父进程终止,则其“僵尸”子进程(如果有)由 init(1) 采用(或由通过使用 pctl(2) PR_SET_CHILD_SUBREAPER 操作定义的最近的“子收割者”进程); init(1) 自动执行等待以删除僵尸。

所以,wait()对于子进程来说,还是会一直挂着,直到父进程死掉。

答案2

我想我找到了解决方案。如果我按如下方式更改kill部分:

      ...
      { 
      printf("child %d about to be killed wait 15 so that htop has time to see it\n",childpid);
      sleep(15);
      kill(childpid, SIGKILL);  
      waitpid(childpid,&ret,WUNTRACED);
      }
   }
return 1;
}

添加 waitpid 似乎可以清除 HTOP 中的进程。如果有人知道任何警告(为什么我应该使用 SIGKILL 而不是 SIGTERM 或者我应该使用 WUNTRACED 以外的其他东西?)请让 Mr 知道。

相关内容