프로세스가 언제 종료되었는지 어떻게 알 수 있나요?

프로세스가 언제 종료되었는지 어떻게 알 수 있나요?

다음 코드는 긴 nmap 프로세스를 시작한 다음 기본 프로그램이 이를 종료하려고 시도합니다. 나는 그것을 쉘에서 실행했고 모든 것이 성공했는지 확인하기 위해 다른 창에서 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리눅스의 경우:

하위 프로세스가 종료되는 경우 대기를 수행하면 시스템이 하위 프로세스와 관련된 리소스를 해제할 수 있습니다. 대기가 수행되지 않으면 종료된 하위 프로세스는 "좀비" 상태로 유지됩니다(아래 참고 참조).

그리고 댓글에서:

종료되었지만 아직 대기하지 않은 하위 프로세스는 "좀비"가 됩니다. 커널은 부모 프로세스가 나중에 자식 프로세스에 대한 정보를 얻기 위해 대기를 수행할 수 있도록 좀비 프로세스에 대한 최소한의 정보 세트(PID, 종료 상태, 리소스 사용 정보)를 유지합니다. 좀비 프로세스는 대기하여 시스템에서 제거되지 않는 한 커널 프로세스 테이블의 슬롯을 소비하며 테이블이 가득 차면 더 이상 프로세스를 생성할 수 없습니다. 상위 프로세스가 종료되면 해당 "좀비" 하위 프로세스(있는 경우)는 init(1)(또는 pctl(2) PR_SET_CHILD_SUBREAPER 작업을 사용하여 정의된 가장 가까운 "자식 리퍼" 프로세스)에 의해 자동으로 채택됩니다. 좀비를 제거하려면 대기를 실행하세요.

따라서 wait()하위 프로세스의 경우 상위 프로세스가 종료될 때까지 계속 정지됩니다.

답변2

해결책을 찾은 것 같아요. 킬 부분을 다음과 같이 변경하면:

      ...
      { 
      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의 프로세스가 지워지는 것 같습니다. 주의 사항(SIGTERM 대신 SIGKILL을 사용해야 하는 이유 또는 WUNTRACED가 아닌 다른 것을 사용해야 하는 이유)을 아는 사람이 있으면 Mr에게 알려주십시오.

관련 정보