실제 좀비처럼 좀비 프로세스는 이미 죽었 기 때문에 죽일 수 없습니다.
어떻게 일어나는가
Linux / Unix에서 프로세스가 종료 / 종료되면 프로세스의 모든 정보가 시스템 메모리에서 제거되고 프로세스 디스크립터 만 유지됩니다. 프로세스는 상태 Z (좀비)에 도달합니다. 그의 부모 프로세스는 커널로부터 신호를받습니다 : SIGCHLD
즉, 그의 자식 프로세스 중 하나가 종료 된 후 중단되거나 재개 됨 (이 경우에는 단순히 종료 됨)을 의미합니다.
상위 프로세스는 이제 wait()
자신의 하위 프로세스에서 종료 상태 및 기타 정보를 읽으려면 syscall 을 실행해야합니다 . 그런 다음 설명자가 메모리에서 제거되고 프로세스는 더 이상 좀비가 아닙니다.
부모 프로세스가 wait()
syscall을 호출하지 않으면 좀비 프로세스 디스크립터는 메모리에 남아 뇌를 먹습니다. 일반적으로 위의 절차는 시간이 덜 걸리기 때문에 좀비 프로세스가 표시되지 않습니다.
죽음의 새벽
각 프로세스 디스크립터는 매우 적은 양의 메모리를 필요로하므로 일부 좀비는 실생활처럼 위험하지 않습니다. 하나의 문제는 각 좀비 프로세스가 자신의 프로세스 ID를 유지하고 Linux / Unix 운영 체제에는 제한된 수의 pid가 있다는 것입니다. 잘못 프로그래밍 된 소프트웨어가 많은 좀비 프로세스를 생성하는 경우 더 이상 사용할 수있는 프로세스 ID가 없기 때문에 프로세스를 더 이상 시작할 수 없습니다.
그래서 그들이 큰 그룹에 있다면 그들은 매우 위험합니다 (많은 영화 에서처럼 잘 보여집니다)
우리는 어떻게 좀비 무리로부터 자신을 방어 할 수 있습니까?
헤드 샷은 작동하지만 그 명령을 알 수 없습니다 (프로세스가 이미 종료되어 SIGKILL이 작동하지 않습니다).
글쎄, 당신은 kill을 통해 SIGCHLD를 부모 프로세스로 보낼 수 있지만,이 신호를 무시하면 어떻게됩니까? 유일한 방법은 부모 프로세스를 종료하고 init 프로세스가 좀비를 "채택"하는 것입니다. Init은 주기적으로 wait()
syscall을 호출하여 좀비 자녀를 정리합니다.
당신의 경우
귀하의 경우 SIGCHLD를 crond 프로세스로 보내야합니다.
root@host:~# strace -p $(pgrep cron)
Process 1180 attached - interrupt to quit
그런 다음 다른 터미널에서 :
root@host:~$ kill -17 $(pgrep cron)
출력은 다음과 같습니다.
restart_syscall(<... resuming interrupted call ...>) = ? ERESTART_RESTARTBLOCK (To be restarted)
--- SIGCHLD (Child exited) @ 0 (0) ---
wait4(-1, 0x7fff51be39dc, WNOHANG, NULL) = -1 ECHILD (No child processes) <-- Here it happens
rt_sigreturn(0xffffffffffffffff) = -1 EINTR (Interrupted system call)
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=1892, ...}) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {0x403170, [CHLD], SA_RESTORER|SA_RESTART, 0x7fd6a7e9d4a0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({42, 0}, ^C <unfinished ...>
Process 1180 detached
wait4()
syscall이 -1 ECHILD를 반환 하는 것을 볼 수 있습니다. 이는 자식 프로세스가 없음을 의미합니다. cron은 SIGCHLD syscall에 반응하며 종말을 강요해서는 안됩니다.