시그널

신호(signal)는 어떤 특정한 조건이 발생했음을 프로세스에게 알려주는 기법이다. 예를 들어 한 프로세스에서 0으로 나누기 예외가 발생하면 그 프로세스에게 SIGFPE(floating-point exception; 부동소수점 예외)라는 이름의 신호가 전송된다. 프로세스가 그러한 신호에 대해 할 수 있는 일은 다음 세 가지 중 하나이다.

  1. 신호를 무시한다. 단, 0으로 나누기나 프로세스의 주소 공간 바깥의 메모리 참조 같은 하드웨어 예외를 뜻하는 신호는 그 결과가 정의되지 않으므로 무시하지 않는 것이 바람직하다.
  2. 기본 동작이 일어나게 한다. 0으로 나누기 조건의 경우 기본 동작은 프로세스의 종료이다.
  3. 신호를 처리할 함수가 호출되게 한다(이를 가리켜 "신호를 잡는다[catch]"라고 말한다). 신호 발생 시 호출될 함수를 미리 지정해 놓으면 프로그램은 신호가 언제 발생했는지 알 수 있으며 신호를 자신이 원하는 방식으로 처리할 수 있게 된다.

신호가 발생하는 조건은 많다. 예를 들어 터미널에는 현재 실행 중인 프로세스의 실행을 가로채는 키가 두 개 있는데, 하나는 가로채기 키(interrupt key)이고 또 하나는 중지 키(quit key)이다. 전자는 흔히 DEL 키나 Ctrl-C 키이고 후자는 Ctrl-\이다. kill 함수를 호출해서 신호를 발생시킬 수도 있다. 이를 이용하면 한 프로세스에서 다른 프로세스에게 신호를 보내는 것이 가능하다. 물론 제약이 있다. 다른 프로세스에게 신호를 보내려면, 해당 사용자가 다른 프로세스(신호를 받는)의 소유자(또는 슈퍼사용자)이어야 한다. 1

시그널 목록

man signal

[[/cmd/kill]] 명령을 통해서도 시그널 목록을 확인할 수 있다.

kill -l

다음은 '유닉스·리눅스 시스템 관리 핸드북 5/e'에서 소개하는 '시스템 관리자가 반드시 알아야 할 시그널' 목록이다. (시스템별로 다를 수 있으니 man signal을 확인할 것.)2

# 이름 설명 기본 액션 캐치 가능? 차단 가능? 코어 덤프?
1 HUB 행업(Hangup, 단절) 종료 아니요
2 INT 인터럽트(Interrupt) 종료 아니요
3 QUIT 중단(Quit) 종료
9 KILL 킬(Kill) 종료 아니요 아니요 아니요
10 BUS 버스 오류(Bus error) 종료
11 SEGV 세그먼테이션 폴트
(Segmentation fault)
종료
15 TERM 소프트웨어 종료 종료 아니요
17 STOP 중지(Stop) 중지 아니요 아니요 아니요
18 TSTP 키보드 중지 중지 아니요
19 CONT 중지 후 계속 무시 아니요 아니요
28 WINCH 윈도우 변경 무시 아니요
30 USR1 사용자정의 #1 종료 아니요
31 USR2 사용자정의 #2 종료 아니요

KILL, INT, TERM, HUP, QUIT 비교

KILL, INT, TERM, HUP, QUIT 시그널이 모두 비슷한 의미로 들릴 수 있겠지만 실질적인 용도는 매우 다르다. 그렇게 모호한 용어가 선택된 것은 불행한 일이다. 다음은 그 의미의 해석을 돕는 가이드다.

  • KILL은 차단 불가능하며 프로세스를 커널 수준에서 종료한다. 프로세스 는 절대 이 시그널을 수신하거나 처리할 수 없다.
  • INT는 사용자가 CTRL+C를 눌렀을 때 터미널 드라이버에 의해 전송된다. 현재 작업을 중단하라는 요청이다. 간단한 프로그램은 이 시그널을 받았을 때 실행을 중단하거나 커널이 자신을 죽이는 것을 허용해야만 한다. 시그널을 캐치하지 않으면 후자가 기본값으로 설정된다. 셸과 같은 대화형 커맨드라인은 현재 실행 중인 것을 중지하고 모든 것을 정리한 후 다시 사용자 입력을 기다려야 한다.
  • TERM은 실행을 완전하게 종결하라는 요청이다. 수신 프로세스는 자신의 상태를 정리하고 빠져나간다.
  • HUP은 일반적으로 두 가지 해석이 가능하다.
    • 첫째, 데몬에 의한 리셋 요청으로 해석된다. 어떤 데몬이 재시작하지 않고 환경설정 파일을 다시 읽어서 변경 사항을 적용하려면 HUP 시그널이 그런 일을 수행하게 만들 수 있다.
    • 둘째, HUP 시그널은 어떤 특정 터미널에 연결된 프로세스들을 '정리'(즉, [[/cmd/kill]]{kill})하려는 시도로 종종 터미널 드라이버에 의해 생성된다. 이런 행위는 유선 터미널과 모뎀 접속을 사용하던 시절부터 지속돼 온 것이다. 그래서 이름도 연결을 끊는다는 의미에서 'hangup'인 것이다.
      C셸 패밀리(tcsh 등)에서 셸은 보통 백그라운드 프로세스가 HUP 시그널에 영향을 받지 않게 함으로써 사용자가 로그아웃한 후에도 백그라운드 프로세스가 계속 실행되게 한다. 본셸 계열(ksh, bash 등)의 사용자는 nohup 명령을 이용해 같은 효과를 구현할 수 있다.
  • QUIT는 캐치되지 않을 경우 기본적으로 코어 덤프가 만들어진다는 점 외에는 TERM과 같다. 일부 프로그램에서는 이 시그널을 다른 용도로 변형해서 사용하기도 한다. 3

함께 읽기

  • [[/cmd/kill]]

참고문헌

  • UNIX 고급 프로그래밍 [제3판] / 리처드 스티븐스, 스티븐 레이고 공저 / 류광 역 / 퍼스트북 / 인쇄일: 2014년 08월 28일 / 원제: Advanced Programming in the UNIX Environment
  • 유닉스·리눅스 시스템 관리 핸드북 5/e / 에비 네메스, 가스 스나이더, 트렌트 헤인, 벤 웨일리, 댄 맥킨 저 외 2명 / 에이콘출판사 / 발행: 2022년 01월 03일 / 원제: UNIX and Linux System Administration Handbook, 5th Edition

주석

  1. UNIX 고급 프로그래밍. 1.9장. 23쪽. 

  2. 유닉스·리눅스 시스템 관리 핸드북 5/e. 4장. 188쪽. 

  3. 유닉스·리눅스 시스템 관리 핸드북 5/e. 4장. 189쪽.