프로세스에 kill -9를 전송하면 프로세스의 협력 (예 : 신호 처리)이 필요하지 않으며 프로세스를 종료합니다.
일부 신호는 포착되어 무시 될 수 있기 때문에 모두 협력이 필요하다고 가정합니다. 그러나에 따르면 man 2 signal
" SIGKILL 및 SIGSTOP 신호 는 포착하거나 무시할 수 없습니다". SIGTERM이 포착 될 수 있습니다. 이것이 평범한 kill
것이 항상 효과적인 것은 아닙니다. 일반적으로 이것은 프로세스 처리기의 무언가가 잘못되었음을 의미합니다. 1
프로세스가 주어진 신호에 대한 핸들러를 정의 할 수 없거나 정의 할 수없는 경우 커널은 기본 동작을 수행합니다. SIGTERM 및 SIGKILL의 경우 프로세스가 종료됩니다 (PID가 1이 아니고 커널이 종료되지 않는 한 init
) 2 파일 핸들이 닫히고 메모리가 시스템 풀로 리턴되고 상위가 SIGCHILD, 고아를 수신함을 의미합니다. 자식은 마치 호출 한 것처럼 init 등으로 상속됩니다 exit
(참조 man 2 exit
). 좀비로 끝나지 않는 한 프로세스는 더 이상 존재하지 않습니다.이 경우 프로세스는 여전히 커널의 프로세스 테이블에 몇 가지 정보와 함께 나열됩니다. 그것은 부모가하지 않을 때 발생wait
이 정보를 올바르게 처리하십시오. 그러나 좀비 프로세스에는 더 이상 할당 된 메모리가 없으므로 계속 실행할 수 없습니다.
리눅스가 프로세스가 차지하는 모든 리소스에 대한 참조를 유지하고 프로세스를 "킬"할 때 리눅스가 단순히 해당 테이블을 통과하고 리소스를 하나씩 해제하는 전역 테이블과 같은 것이 있습니까?
나는 그것이 정확하다고 생각합니다. 실제 메모리는 페이지 (일반적으로 4KB 청크와 같은 한 페이지)별로 추적되며 해당 페이지는 전역 풀에서 가져 와서 반환됩니다. 포함 된 데이터가 다시 필요한 경우 (즉, 기존 파일에서 읽은 데이터) 사용 가능한 일부 페이지가 캐시되는 것이 조금 더 복잡합니다.
맨 페이지는 "신호"에 대해 이야기하지만 반드시 추상화 일뿐입니다.
물론 모든 신호는 추상화입니다. 그것들은 "프로세스"와 같은 개념입니다. 나는 의미론을 약간 연주하고 있지만 SIGKILL이 SIGTERM과 질적으로 다르다는 것을 의미한다면, 그렇습니다. 잡을 수 없다는 의미에서 그렇습니다. 그러나 둘 다 신호라는 의미에서는 아닙니다. 유사하게, 사과는 오렌지가 아니지만 사과와 오렌지는 선입관에 따르면 과일입니다. SIGKILL은 잡을 수 없기 때문에 더 추상적 인 것처럼 보이지만 여전히 신호입니다. SIGTERM 처리의 예는 다음과 같습니다.
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
void sighandler (int signum, siginfo_t *info, void *context) {
fprintf (
stderr,
"Received %d from pid %u, uid %u.\n",
info->si_signo,
info->si_pid,
info->si_uid
);
}
int main (void) {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = sighandler;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGTERM, &sa, NULL);
while (1) sleep(10);
return 0;
}
이 과정은 영원히 잠들 것입니다. 당신은 터미널에서 그것을 실행하고 함께 SIGTERM을 보낼 수 있습니다 kill
. 그것은 다음과 같은 것들을 뱉어냅니다.
Received 15 from pid 25331, uid 1066.
1066은 내 UID입니다. PID kill
는 실행 되는 쉘 의 PID이거나 포크하면 킬의 PID입니다 ( kill 25309 & echo $?
).
다시 말하지만 SIGKILL의 핸들러는 작동하지 않기 때문에 아무런 의미가 없습니다. 3 내가 kill -9 25309
프로세스를 종료합니다. 그러나 그것은 여전히 신호입니다. 커널은 누가 신호 를 보냈 는지, 어떤 종류의 신호 인지 등에 대한 정보를 가지고 있습니다 .
1. 가능한 신호 목록을 보지 않은 경우을 참조하십시오 kill -l
.
2. Tim Post가 아래에 언급 한 것처럼 또 다른 예외는 무정전 수면 프로세스에 적용됩니다 . 근본적인 문제가 해결 될 때까지 깨울 수 없으므로 지속 기간 동안 모든 신호 (SIGKILL 포함)가 지연됩니다. 그러나 프로세스는 이러한 상황을 의도적으로 만들 수 없습니다.
3. 이것이 kill -9
실제로 사용 하는 것이 더 좋은 것을 의미하지는 않습니다 . 내 예제 핸들러는로 이어지지 않는다는 점에서 나쁜 것입니다 exit()
. SIGTERM 핸들러의 실제 목적은 프로세스에 임시 파일 정리와 같은 작업을 수행 한 다음 자발적으로 종료하는 것입니다. 를 사용 kill -9
하면이 기회를 얻지 못하므로 "자발적으로 종료"한 부분이 실패한 것만 가능합니다.
kill -9
참조 .