LabHub

리눅스 기초 · 프로세스와 신호 · 실습

프로세스와 시그널 다루기

LabHub 에서 이어서 보기

목표

프로세스에 시그널을 보내며 정지·종료·강제 종료가 각각 무엇이 다른지 확인하고, 좀비가 어떻게 생기는지 직접 만들어 봅니다.

왜 중요한가

"프로세스가 안 죽는다"는 신고는 최소 네 가지 다른 상황을 뭉뚱그린 말입니다. 애플리케이션이 SIGTERM 을 잡아 무시했을 수도 있고, D 상태라 시그널 처리 자체가 미뤄졌을 수도 있고, 이미 죽어서 좀비로 남은 것일 수도 있습니다. 대응이 전부 다르기 때문에 어느 계층에서 멈췄는지를 먼저 물어야 합니다. 그리고 SIGKILL 과 SIGSTOP 만 잡을 수 없다는 규칙은 커널이 운영자에게 남겨 둔 최후의 수단입니다 - 그래서 SIGKILL 은 정리 기회를 주지 않고, DB 나 큐 소비자에게는 전원을 뽑는 것과 같습니다.

단계

1. sleep 3600 을 백그라운드로 띄우고 그 PID 를 /root/proc/pid.txt 에 적으세요.
2. 그 프로세스의 부모 PID/root/proc/ppid.txt 에 적으세요.
3. 또 다른 sleep 을 띄워 정지(SIGSTOP) 시키고, PID 를 /root/proc/stopped_pid.txt 에, 정지 후의 상태 글자 한 개를 /root/proc/state_stopped.txt 에 적으세요.
4. 또 다른 sleep 을 띄워 PID 를 /root/proc/killed_pid.txt 에 적은 뒤 SIGTERM 으로 종료시키세요.
5. /root/proc/trapper.sh 를 만드세요. SIGTERM 을 받으면 /root/proc/term.logcaught SIGTERM 한 줄을 추가해야 합니다. 실행 권한을 주고 백그라운드로 띄운 뒤 SIGTERM 을 보내 로그가 쌓이는지 확인하세요.
6. trapper.sh 를 다시 띄우고 이번엔 SIGKILL 을 보내세요. 보내기 직전 term.log 의 줄 수를 /root/proc/before_kill.txt 에, 보낸 직후의 줄 수를 /root/proc/after_kill.txt 에 적으세요. 실습이 끝나면 trapper.sh 는 하나도 살아 있으면 안 됩니다.
7. 자식을 하나 낳고 그 자식이 먼저 끝나도록 하되, 부모는 wait 하지 않고 계속 살아 있게 만드세요. 그 부모의 PID/root/proc/zombie_parent.txt 에 적으세요.
8. /root/proc/cleanup.sh <패턴> 을 만드세요. 명령줄이 그 패턴에 맞는 프로세스를 모두 종료하고, 종료한 개수를 terminated=<n> 형식으로 한 줄 출력해야 합니다. 자기 자신은 세지도 죽이지도 않아야 합니다.

참고

단계 8개

  1. 백그라운드 프로세스 띄우기
  2. 부모 PID 확인하기
  3. 프로세스 정지시키기
  4. 정중하게 종료 요청하기
  5. SIGTERM 을 잡는 스크립트
  6. SIGKILL 은 잡히지 않는다
  7. 좀비 만들어 보기
  8. 패턴 기반 정리 스크립트