UNIX계열 OS인 Linux(ex. ubuntu, macOS-BSD, Darwin)는 커널단에서 시그널을 사용하여 프로세스에 다양한 명령을 내릴 수가 있다
macOS에서 테스트해보려고 한다
일단 macOS에서 가능한 kill 옵션(인자)를 확인해보자
kill -l
손으로 일일이 세도 되지만 깔쌈하게 몇개의 인자를 갖고 있는지 아래의 명령어로 확인해보자
kill -l | tr ' ' '\n' | tee /dev/tty | wc -l | xargs echo "total command count:"
macOS에서는 kill 관련 31개의 인자를 쓸 수 있다
이중 프로세스 종료와 관련된 것은 1(HUP), 2(INT), 3(QUIT), 6(ABRT), 9(KILL), TERM(15) 이렇게 있다
SIG라는 것은 SIGNAL(신호)의 줄임말이다
각각의 차이점
1(SIGHUP) - SIGnal Hang UP
- 발생상황: 네트워크 연결이 끊어졌을 때, 데몬 관련 설정을 변경시키고 재시작 할때
- 핸들링: O
- 코어덤프: X
2(SIGINT) - SIGnal INTerrupt
- 발생상황: 키보드의 인터럽트 시그널(Ctrl + C)을 프로세스에 전송
- 핸들링: O
- 코어덤프: X
3(SIGQUIT) - SIGnal QUIT
- 발생상황: 키보드의 인터럽트 시그널(Ctrl + \)을 프로세스에 전송 [백스페이스]
- 핸들링: O
- 코어덤프: O
6(SIGABRT) - SIGnal ABoRT
- 발생상황: C와 C++에서 assert 매크로에서 실패한 경우, 메모리 할당 오류(malloc), C/C++ 프로그램 내부에서 abort() 호출
- 핸들링: O
- 코어덤프: O
9(SIGKILL) - SIGnal KILL
- 특징: forceful kill, hard termination이라고도 불림
- 발생상황: kill -9 시그널을 전달한 경우, OOM(Out of Memory)이 발생한 경우
- 핸들링: X
- 코어덤프: X
15(SIGTERM) - SIGnal TERMinate
- 특징: graceful kill, soft termination이라고도 불림
- 발생상황: kill 또는 kill -15 시그널을 전달한 경우, 시스템 종료 또는 재시작을 하는 경우
- 핸들링: O
- 코어덤프: X
Q. 코어덤프란?
A. 컴퓨팅에서, 코어 덤프(core dump), 메모리 덤프(memory dump), 또는 시스템 덤프(system dump), ABEND 덤프는 컴퓨터 프로그램이 특정 시점에 작업 중이던 메모리 상태를 기록한 것으로, 보통 프로그램이 비정상적으로 종료했을 때 만들어진다. 실제로는, 그 외에 중요한 프로그램 상태도 같이 기록되곤 하는데, 프로그램 카운터, 스택 포인터 등 CPU 레지스터나, 메모리 관리 정보, 그 외 프로세서 및 운영 체제 플래그 및 정보 등이 포함된다. 코어 덤프는 프로그램 오류 진단과 디버깅에 쓰인다.
https://ko.wikipedia.org/wiki/%EC%BD%94%EC%96%B4_%EB%8D%A4%ED%94%84
핸들링에 대해 O, X로 되어있는 이유는 핸들러를 만들고 시스템 콜을 후킹을 할 수 있는지 여부이다
간단하게 singal_test 쉘 파일을 만들어서
SIGINT(Ctrl+C), SIGTERM(kill), SIGQUIT(Ctrl+\)에 대한 핸들러를 만들어서 추가해보자
vi signal_test.sh
#!/bin/sh
handle_sigint() {
echo "SIGINT received! Exiting..."
exit 0
}
handle_sigterm() {
echo "SIGTERM received! Doing cleanup..."
sleep 3
echo "Cleanup done!"
exit 0
}
handle_sigquit() {
echo "SIGQUIT received!..."
exit 0
}
# SIGINT와 SIGTERM에 대한 핸들러 설정
trap handle_sigint INT
trap handle_sigterm TERM
trap handle_sigquit QUIT
echo "Script PID is: $$"
echo "Running... Press Ctrl+C to exit or send signals using kill command."
while true; do
sleep 1
done
실행권한을 부여하고
chmod +x signal_test.sh
실행해보자
./signal_test.sh
테스트 방법
터미널을 하나 더 열어놓고 도커 내부로 cmd를 전달해서 테스트해본다
⇒ terminal 열린 창에서 cmd + t: 새로운 탭 열기
키보드 인터럽트로 2개의 핸들러를 테스트를 해본다
Ctrl+C, Ctrl +\
이번에는 kill [ARG] pid 명령어 테스트를 해보자
> kill -2 pid 또는 kill -INT pid
> kill -3 pid 또는 kill -QUIT pid
> kill -9 pid 또는 kill -KILL pid
마지막으로 > kill pid(기본) 또는 kill -15 pid 또는 kill -TERM pid
SIGKILL과 SIGTERM의 차이점
SIGKILL은 프로세스를 중지하라는 요청이 들어오면, 처리하고 있는 작업이 있더라도 바로 종료가 되기때문에 시스템콜을 hooking해서 handler를 동작하게 할 수 없다 => forceful kill
SIGTERM은 프로세스를 중지하라는 요청이 들어오면, 시스템콜을 hooking해서 handler를 만들어서 처리하고 있는 작업을 먼저 끝내고, 프로세스가 종료되게 만들 수 있다 => graceful kill
다음번에는 docker카테고리에 올렸던 CLI글을 기반으로(https://code-boki.tistory.com/128) docker를 이용해서 ubuntu, alpine 이미지 위에서 docker CLI(attach & exec)로 컨테이너의 프로세스를 중지시켜 볼 것이다
그리고 Spring환경, Express, Nest, Django 등에서는 어떻게 graceful kill을 지원 또는 구현하는지에 대해서도 올릴 예정이다
'OS > Linux' 카테고리의 다른 글
UTM Virtual Machine으로 M1 Mac에서 Ubuntu LTS 버전 설치하기(2023.06) (1) | 2023.06.08 |
---|---|
파일 크기와 권한 등을 볼 수 있는 명령어 & Mac (0) | 2022.08.27 |
댓글