SIGNAL이란??
OS (LINUX 및 UNIX계열)에서의 SIGNAL은
UNIX 또는 UNIX 계열 또는 POSIX 호환 OS에서
제한된 형태의 Inter-Process Communication (IPC)와
비동기 event처리를 위해 사용되는
독립적인 비동기적 이벤트 처리 메커니즘임:
- signal은 OS가 생성,관리, 전달을 책임짐.
- s/w interrput는 cpu가 s/w interrupt 명령(INT)을 감지하면,
현재 실행코드 중단하고, OS의 ISR로 제어를 넘김.
특정 process가
동일 process 내의 thread 또는 다른 process에
메시지를 비동기식으로 보낼 때 SIGNAL을 사용함 (비동기식 통보).
SIGNAL은 프로세스에 어떤 Event가 발생했음을 알리기위해 사용되는 비동기 메커니즘으로 프로세스 단위로 동작하나,
Software Interrupt (system call과 kernel mode전환을 위해 cpu 명령어에 의해 발생) 와 매우 유사함.
많은 경우
kill 이라는 system call을 통해
process 는 os를 통해 다른 process에 SIGNAL을 전달!!
https://dsaint31.me/mkdocs_site/CE/ch05/ch05_04_02_interrupt/#os-signal-or-event-handler-system
https://dsaint31.tistory.com/447
OS (특히 linux)에서 SIGNAL의 종류는 크게
- User가 interrupt key를 통해 발생시키는 SIGNAL:
CTRL+c
: SIGINT, ineterruptCTRL+z
: SIGTSTP, user가 일시적으로 실행정지
- Process가 발생시키는 SIGNAL
kill
함수 등과 같은 system call, ** (자주 이용되는 방식)- 또는 SW의 condition에 따른 alarm 등,
- H/W에서 발생시키는 SIGNAL
- eq. Hardware Exception 로 대표적인 경우가 Zero Division 등이 있음
- H/W 에서 event가 발생하고, (이를 처리하기 위해) OS에 제어권이 넘겨지고, OS가 상황을 분석하여 적절한 SIGNAL을 발생시켜 적절한 프로세스에 전달
- 즉, OS가 event (주로 exception)를 분석하여 SIGNAL로 변환.
등으로 나눌 수 있으며 보통 특정 event가 발생할 경우 관련된 process에게 전달할 때 사용된다.
H/W에서 발생하는 SIGNAL(동기/비동기 모두 가능)과 달리
H/W interrupt는 항상 비동기이고, 직접 CPU에게 전달되어 적절한 Interrupt Service Routine(ISR)이 수행됨.
SIGNAL 목록 확인하기
OS 종류에 따라 지원하는 SIGNAL 목록은 차이가 있으며 kill
명령어에 -l
옵션을 주어 실행시키면 확인 가능함.
다음은 bash 에서 수행한 경우임.
(base) ubuntu@mylinux:~$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
- 위의 결과는 Ubuntu에서 bash 셀에서
kill -l
을 수행한 결과임. - 앞의 번호는 해당 SIGNAL에 할당된 번호로 각 SIGNAL별로 유일하게 할당된다.
- kill 명령어에서 해당 번호를 통해 특정 프로세스에 SIGNAL을 보낼 수 있음. (
raise
,abort
,sigsend
등을 이용하는 것도 가능함)
각 signal에 대한 상세 내용은 아래의 "signal의 종류" 항목을 참고할 것.
참고로 다음은 zsh에서 수행한 경우임.
HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM
TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM
PROF WINCH POLL PWR SYS
KILL
명령어를 통한 SIGNAL 보내기
좋은 참고 자료: https://www.lesstif.com/system-admin/unix-linux-kill-12943674.html
다음의 세가지 방법은 모두 동일한 동작을 수행함.
kill -1 TARGET_PID
kill -SIGHUP TARGET_PID
kill -HUP TARGET_PID
TARGET_PID
는ps
등을 통해 확인가능한 프로세스에 할당된 process id를 의미함.TARGET_PID
가0
일 경우, 현재kill
명령을 호출한 쉘(shell)의 GID에 속하는 프로세스 그룹의 모든 프로세스들에 전송됨.TARGET_PID
가-1
일 경우, 현재kill
명령을 호출한 User와 동일한 UID를 가진 모든 프로세스에 SIGNAL이 전송됨.TARGET_PID
가-1
보다 작은 경우, 주어진TARGET_PID
의 절대값과 동일한 GID를 가진 프로세스 그룹의 모든 프로세스들에 전송됨.- 참고로 root 만이 다른 사용자의 processes에 SIGNAL을 보낼 수 있으며 일반 User는 자신이 processes에만 SIGNAL을 보내는게 일반적임.
TARGET_PID
를 얻기 위해서ps
가 많이 사용되나top
,pidof
,pgrep
들도 많이 사용됨.TARGET_PID
는 복수개가 주어질 수 있으며, 스페이스를 통해 구분됨.
kill 명령어 뒤에 - (dash) 를 이용하여 singal의 종류를 정하는데,
만약 signal 종류를 지정하지 않고 대상 process id만 지정할 경우,
SIGTERM 이 보내짐.
kill -9 (SIGKILL)는 최후의 방법이고, 가급적 SIGTERM을 이용하여 프로세스를 종료하는 게 좋음.
SIGHUP
는 위의 방식으로 보내질 경우,
TARGET_PID
에 해당하는 프로세스를 종료 후 재시작시킴(우선 종료하고, 관련 설정을 다시 로드하여 수행시킴).- 또한 해당 signal은 terminal의 session이 종료될 때 사용 중이던 shell에 SIGHUP이 전달되고, 해당 shell로부터 실행했던 모든 프로세스들(jobs 로 확인 가능)에 보내져서 그들이 종료되도록 함.
- 때문에 ssh 등으로 접속하여 수행시킨 프로세스를 해당 ssh 연결을 끊은 이후에도 수행되게 하려면
nohup
등을 통해 이 signal을 무시하도록 처리해야함.
이에 대해선 다음 URL을 참고.
2023.09.29 - [Linux] - [Linux] 터미널 종료와 상관없이 지속 실행되는 process 만들기 : nohup, tmux
SIGNAL Handler
앞서 살펴본 kill
을 통해 SIGNAL을 보내는 방식으로 주로 사용되는 SIGNAL은 종료 9
(SIGKILL
)을 주로 사용하다. (kill이 괜히 프로세스 킬러 명령어로 불리는 게 아님)
하지만, SIGNAL은 프로세스간 통신을 위한 것으로 특정 방식으로 다르게 처리되어야 하는 경우도 있음.
SIGNAL을 수신한 프로세스의 반응은 다음과 같이 크게 3가지로 나뉨.
- 해당 SIGNAL에 지정된 처리 방식으로 반응함 (예를 들어
SIGKILL
을 받은 경우, 해당 프로세는 종료됨)- Term (Terminate) : 프로세스 종료
- Core (Terminate + Core dump) : 프로세스 종료 및 dump core를 수행. (core란 memory dump 파일로 디버깅에서 요구되는 정보를 가짐. 주로 pointer가 잘못된 곳을 참조하는 경우 많이 발생.)
- Stop : 정지 (일지 정지)
- Cnt (Continue) : 정지된 프로세스를 이어서 다시 실행시킴.
- Ign (Ignore) : 무시
- 수신한 SIGNAL을 무시한다 (무시하도록 지정된 경우로
nohup
로 수행된 프로세는SIGHUP
을 무시함)SIGKILL
과SIGSTOP
은 무시할 수 없음.
- 해당 SIGNAL에 대해 프로그래머가 지정한 SIGNAL Handler를 호출하여 수행.
특히 3번의 경우는 프로그래머가 코드로 특정 SIGNAL을 수신한 경우 수행될 별도의 함수를 지정 및 구현한 경우로 해당 함수를 signal handler라고 부름.
- 이 경우, 해당 SIGNAL을 수신한 프로세스는 기존의 수행하던 작업을 일시 중단하고 signal handler를 수행함.
- 해당 signal handler의 수행이 종료되며 해당 프로세스는 중단된 작업을 재개하게 된다.
SIGNAL 처리 방식 (일반)
- 이벤트 발생으로 SIGNAL 생성 (Kernel에서 SIGNAL을 생성)
- 프로세스는 signal mask를 사용하여 특정 SIGNAL을 block 또는 unblock시킴.
- 생성된 SIGNAL이 타겟 프로세스에서 Block 처리된 경우,
- 타켓 프로세스가 이후 unblock이 되어 수신 가능상태가 되기 전까지, 또는
- 해당 처리가 Ign (무시)로 변경(해당 SIGNAL이 처리되지 않게됨)되기 전까지
- Pending이 됨.
- Pending은 생성은 되었지만 해당 프로세스로 전달되지 않은 상태를 의미.
- 타겟 프로세스가 SIGNAL을 수신 (해당 프로세스에 SIGNAL 전달됨)
- "기본 처리" 또는 "사용자 정의 Signal Handling", "Ign(무시)" 중 하나로 처리가 이루어짐.
- 기본처리는 SIGNAL 에 따라 정해진 기본동작:
- 아래 SIGNAL들의 종류 확인:
- 사용자 정의 Signal Handler 의 경우,
- 타겟 프로세스에서 특정 SIGNAL에 대한 사용자 정의 handler 함수가 등록된 경우이며,
- 해당 handler 가 실행된 이후,
- 타겟 process는 SIGNAL 수신 이전의 원래상태로 복귀하여 정상적인 실행을 이어감.
- Ignoring은 SIGNAL을 무시하여 해당 처리를 하지 않는 것임:
- SIGKILL(강제종료) 과 SIGSTOP(일시정지) 은 무시불가!
- 기본처리는 SIGNAL 에 따라 정해진 기본동작:
특정 프로세스에 여러 Signal이 동시에 전달되는 경우, 이들의 처리 순서는 보장되지 않음.
SIGNAL
들의 종류
번호 | Name | Description | 기본 처리 방식 |
1 | SIGHUP |
Hang Up의 약어. terminal의 접속이 끊어질 때 보내지는 signal. 특정 프로그램 (주로 Deamon)의 설정이 변경된 경우, 해당 변경을 반영하여 재시작시키기 위해서 많이 사용됨. 또는 terminal의 접속이 끊어질 때, 관련 process들(해당 session의 jobs에 등록된 프로세스들)의 종료를 위해서 사용됨. |
Term (Terminate) 종료처리 |
2 | SIGINT (INT) |
Interrupt의 약어. User가 키보드에서 CTRL+c 를 입력하여 보내는 interrupt signal임. 기본적으로 해당 프로세스의 실행이 종료됨. |
Term (Terminate) 종료처리 |
3 | SIGQUIT | Quit. User가 키보드에서 CTRL+\ 를 입력하여 보내는 실행중지 signal. 프로세스를 종료시키고 core dump를 수행함. |
Core (terminate process and dump core) |
4 | SIGILL (ILL) |
Illegal instruciton을 의미. 잘못된 명령이 실행된 경우 발생. |
Core (terminate process and dump core) |
5 | SIGTRAP (TRAP) |
Debugger에 의해 사용되는 TRAP (TRAP: S/W에서 system call을 통해 발생시키는 interrupt에서 이용되는 명령어). 디버깅의 tracing이나 breakpoint등에서 발생 |
Core (terminate process and dump core) |
6 | SIGIOT (IOT) |
Abort(비정상 종료) 함수(system call)에 의해 발생. | Core (terminate process and dump core) |
7 | SIGBUS (BUS) |
메모리 접근 에러와 같은 BUS Error 시 발생. 정의되지 않은 메모리 object에 접근하려고 시도하는 경우 등. |
Core (terminate process and dump core) |
8 | SIBFPE (FPE) |
Floating Point Error 부동소수점 산술 연산에서 문제 발생시 |
Core (terminate process and dump core) |
9 | SIGKILL (KILL) |
Kill 의 뜻 그대로 프로세스를 죽인다. (속해있는 threads에게 정리할 시간을 주는 SIGTERM과 달리 즉시 강제종료시킴) |
Term (Terminate) 종료처리 |
10 | SIGUSR1 (USR1) |
사용자 정의 신호 1 | Term (Terminate) 종료처리 |
11 | SIGSEGV (SEGV) |
Segmentation Violation 유효하지 않은 메모리 접근으로 인한 에러 (invalid memory ref등을 사용). |
Core (terminate process and dump core) |
12 | SIGUSR2 (USR2) |
사용자 정의 신호 2 | Term (Terminate) 종료처리 |
13 | SIGPIPE (PIPE) |
읽어들이는 프로세스 없이 파이프에 기록하려고 시도하는 경우 발생 예를 들면, 종료된 socket에 쓰기를 시도하는 경우. |
Term (Terminate) 종료처리 |
14 | SIGALRM (ALRM) |
alarm signal. alarm(n) 을 통해 n초 후 해당 signal발생되도록 할 수 있음. |
Term (Terminate) 종료처리 |
15 | SIGTERM (TERM) |
Terminate 가능한 정상 종료를 시키는 SIGNAL. 대상 프로세스의 자식 threads이 정상적으로 종료되도록 하므로 SIGKILL보다 권장됨. |
Term (Terminate) 종료처리 |
16 | SIGSTKFLT TKFLT |
coprocessor stack fault | |
17 | SIGCHLD CHLD |
프로세스가 stop 또는 terminate 될 때, 해당 프로세스의 부모프로세스에 보내지는 signal | Ign (ignore, 무시) |
18 | SIGCONT (CONT) |
Continue STOP signal 로 정지된 프로세스를 다시 계속해서 실행하기 위해 보내지는 signal. 만일 stop상태가 아니면 무시된다. |
Cont continue the process if it is currently stopped. |
19 | SIGSTOP (STOP) |
SIGTSTP 와 함께 프로세스를 정지시키기 위해 사용됨. 사용자가 사용하는 SIGTSTP와 달리 OS가 프로세스를 강제종료하는 용도로사용. 때문에 TSTP 와 달리 무시되거나 잡히지 않음. |
Stop 정지. (프로세스를 멈춤) |
20 | SIGTSTP (TSTP) |
Terminal SToP 의 약어. (tty driver를 통해 전달가능) User가 CTRL+z 를 통해 발생시키며 프로세스를 정지시킴 (사용자가 이용)무시 가능. fg, bg 를 통해 User가 다시 실행시키기 전까지 정지됨. |
Stop 정지. (프로세스를 멈춤) |
21 | SIGTTIN |
BG(백그라운드) 프로세스에서 control tty(제어 터미널에서) 읽기가 이루어질 경우. | Stop 정지. (프로세스를 멈춤) |
22 | SIGTTOU |
BG(백그라운드) 프로세스에서 control tty(제어 터미널로) 쓰기가 이루어질 경우. | Stop 정지. (프로세스를 멈춤) |
23 | SIGURG |
socket에서 긴급 메시지 또는 제어신호를 의미하는 OOB (Out Of Band) Data를 받은 경우 발생. | Ign (ignore, 무시) |
24 | SIGXCPU |
CPU 시간 제한 초과 | Core (terminate process and dump core) |
25 | SIGXFSZ |
파일 크기 제한 초과 | Core (terminate process and dump core) |
26 | SIGVTALRM |
가상 타이머 시간 초과 알림(경고) | Term (Terminate) 종료처리 |
- 붉은 색으로 번호가 기재된 경우, 대부분의 linux에서 고정된 signal 번호인 경우를 의미함.
- /usr/include/asm-generic 의 siginfo.h, signal.h 의 파일에서도 확인 가능함.
SIGTERM vs. SIGKILL
다음 만화가 매우 쉽게 설명을 해주고 있음. SIGTERM 의 사용을 권하고 있음.
References
https://blog.naver.com/sanghun0318/220399680353
https://www.ibm.com/docs/ko/i/7.3?topic=concepts-out-band-data
https://jangpd007.tistory.com/90
https://seorenn.blogspot.com/2011/02/sigsegv.html
'Linux' 카테고리의 다른 글
[Linux] SystemV, BSD, 그리고 Linux 간략 역사 (0) | 2023.10.23 |
---|---|
[Linux] 특정 조건의 파일들 찾아 특정 명령어 적용하기 : find -exec (1) | 2023.10.22 |
[Linux] 현재 shell 또는 session의 관련 process들 확인하기 : jobs (0) | 2023.10.22 |
[Bash] 입출력 목적지 변경하기 : Redirection Operation (1) | 2023.10.02 |
[Linux] 한글 처리 : Ubuntu (1) | 2023.10.01 |