맨위로가기

유닉스 신호

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

유닉스 신호는 프로세스 간의 통신 및 제어를 위해 사용되는 소프트웨어 인터럽트이다. 초기 유닉스 시스템에서는 인터럽트, 종료, 머신 트랩을 잡기 위한 시스템 호출이 존재했고, 이후 `kill` 명령어와 `signal` 시스템 호출이 도입되었다. 유닉스 신호는 터미널 키 조합, `kill()` 시스템 호출, 예외 처리 등을 통해 발생하며, 프로세스는 이를 처리하기 위한 시그널 핸들러를 설정할 수 있다. POSIX 표준은 다양한 시그널과 기본 동작을 정의하며, 시그널 처리에는 경합 상태와 시스템 콜 중단 등의 주의사항이 따른다.

2. 역사

유닉스 신호의 개념은 초기 유닉스 시스템에서 발전해왔다. 초기 유닉스는 버전별로 시스템 호출, `kill` 명령어, 트랩 통합 등 다양한 변화를 겪었다. 유닉스 버전 7에서 각 트랩에 기호 이름이 부여되었다.

2. 1. 초기 유닉스

버전 1 유닉스는 인터럽트, 종료, 머신 트랩을 잡기 위해 별도의 시스템 호출을 사용했다.[29] 버전 2 유닉스에서는 `kill` 명령어가 등장했다.[29] 버전 4 유닉스에서는 모든 트랩을 `signal`이라는 하나의 호출로 통합했다.[29] 버전 5 유닉스에서는 임의의 신호를 보낼 수 있게 되었다.[29][1] 버전 7 유닉스에서는 각 번호가 매겨진 트랩에 기호 이름을 부여했다.[29]

버전주요 특징
유닉스 버전 1 (1971년)인터럽트, 종료, 머신 트랩을 잡기 위한 별도의 시스템 호출 사용
유닉스 버전 2 (1972년)`kill` 명령어 등장
유닉스 버전 4 (1973년)모든 트랩을 `signal`이라는 하나의 호출로 통합
유닉스 버전 5 (1974년)임의의 신호 전송 가능[1]
유닉스 버전 7 (1979년)각 트랩에 기호 이름 부여


2. 2. 벨 연구소 및 POSIX 표준화

벨 연구소플랜 9(1980년대 후반)은 신호를 짧고 임의적인 문자열을 보낼 수 있는 "노트"로 대체했다.[2]

AT&T UNIX V4에서 프로세스 시그널 처리를 설정하기 위한 API인 `signal()`이 처음 구현되었다. 이 당시의 시그널은 터미널에서의 간단한 프로세스 제어(주로 수동에 의한 프로세스 종료)를 목적으로 했다. 시그널 마스크는 지원되지 않았으며, 시그널 핸들러의 재진입 방지를 위해 시그널 핸들러 실행 시작 시 시그널 처리를 기본 동작으로 되돌리는 사양이었다. 시그널 핸들러의 재진입을 가능하게 하려면 시그널 핸들러 내에서 시그널 핸들러를 다시 설정해야 했다. 이 당시의 시그널 사양은 이후 4.2BSD에서의 시그널 구현 이후 "신뢰할 수 없는 시그널"이라고 불린다.

시그널이 더욱 범용적인 프로세스 통신 및 제어에 이용되면서, 시그널 핸들러 재설정에서 발생하는 경합이 문제로 떠올랐다. 최초의 개선으로, SVR3은 원시적인 시그널 마스크를 구현하여, 하나의 시그널 마스크 및 해제, 더 나아가 시그널 마스크의 조작과 시그널 대기를 원자적으로 실행하는 것을 지원했다. 이어서 4.2BSD는 복수의 시그널에 대한 묶음 시그널 마스크 조작 및 시그널 핸들러 내에서의 복수의 시그널 마스크를 구현하여, 프로세스 제어를 위해 여러 종류의 시그널을 안전하게 사용할 수 있도록 했다. 또한, 시그널 핸들러에서의 전용 스택이나 프로세스 그룹 대상의 시그널 송신, 시그널 수신 후의 투명한 시스템 콜 재개도 지원하여, 단일 사용자 스레드에서의 "신뢰할 수 있는 시그널"의 시맨틱스를 확립했다. 한편, SVR3, 4.2BSD의 시그널 API는 상호 간의 호환성, 구 구현과의 하위 호환성이 모두 결여되어 이식성 문제를 일으켰다.

이식성 문제는 SVR4에서 `sigaction()`을 중심으로 API를 정리함으로써 해결되었다. `signal()`을 포함한 구 구현과의 하위 호환성은 `sigaction()`의 옵션 기능, 하위 호환성을 위한 시스템 콜이나 라이브러리 함수로 재구현하여 흡수되었다. 그 후, 시그널 표준화 작업은 POSIX로 이어졌고, 멀티 스레드에서의 시그널 사양 확장 등은 POSIX가 담당했다.

3. 시그널 보내기

`stty` 명령으로 터미널의 기본 키 조합을 변경할 수 있다.

`kill(2)` 시스템 콜은 권한이 허용되는 경우 지정된 프로세스에 지정된 시그널을 보낼 수 있다. 마찬가지로, `kill(1)` 명령어를 사용하면 사용자가 프로세스에 시그널을 보낼 수 있다. `raise(3)` 라이브러리 함수는 현재 프로세스에 지정된 시그널을 보낸다.

0으로 나누기, 세그먼테이션 오류(SIGSEGV), 부동 소수점 예외 (SIGFPE)와 같은 예외 처리코어 덤프를 발생시키고 프로그램을 종료한다.

커널은 프로세스에 이벤트를 알리기 위해 신호를 생성할 수 있다. 예를 들어, SIGPIPE는 프로세스가 리더에 의해 닫힌 파이프에 쓰기를 시도할 때 생성된다. 기본적으로 이는 프로세스를 종료시키며, 이는 셸 파이프라인을 구성할 때 편리하다.

3. 1. 터미널 키 조합

실행 중인 프로세스의 제어 터미널에서 특정 키 조합을 입력하면 시스템이 특정 신호를 내보낸다.[3]

  • Ctrl-C (구 유닉스에서는 DEL): SIGINT (인터럽트) 신호를 내보내 프로세스를 종료한다.
  • Ctrl-Z: SIGTSTP (터미널 중지) 신호를 내보내 프로세스 실행을 일시 중단시킨다.[4]
  • Ctrl-\: SIGQUIT (종료) 신호를 내보내 프로세스를 종료시키고 코어 덤프를 생성한다.
  • Ctrl-T (모든 유닉스에서 지원하지는 않음): SIGINFO (정보) 신호를 내보낸다. 운영 체제가 실행 중인 명령어에 대한 정보를 표시한다.[5]


이러한 키 조합은 `stty` 명령으로 변경할 수 있다.

3. 2. 시스템 호출 및 명령어

`kill(2)` 시스템 콜은 권한이 허용되는 경우 지정된 프로세스(군)에 지정된 시그널을 보낼 수 있다.[3] 마찬가지로 `kill(1)` 명령어를 사용하면 사용자가 프로세스(군)에 시그널을 보낼 수 있다.[3] `raise(3)`를 사용하면 현재 프로세스(또는 스레드)에 지정된 시그널을 전송할 수 있다.[3]

3. 3. 예외 처리 및 커널 이벤트

0으로 나누기나 세그먼테이션 오류(SIGSEGV), 부동 소수점 예외 (SIGFPE)와 같은 예외 처리코어 덤프를 발생시키고 프로그램을 종료한다.[3]

커널은 프로세스에 이벤트를 알리기 위해 신호를 생성할 수 있다. 예를 들어, SIGPIPE는 프로세스가 리더에 의해 닫힌 파이프에 쓰기를 시도할 때 생성된다. 기본적으로 이는 프로세스를 종료시키며, 이는 셸 파이프라인을 구성할 때 편리하다.[3]

4. 시그널 처리

프로세스는 `signal()` 또는 sigaction() 시스템 호출을 사용하여 시그널 핸들러를 설정할 수 있다. 시그널 핸들러가 설정되지 않은 경우에는 기본 핸들러가 사용된다.

4. 1. 기본 동작

signal(2) 또는 sigaction(2) 시스템 호출을 사용하여 신호 처리기를 설치할 수 있다. 특정 신호에 대해 신호 처리기가 설치되지 않은 경우, 기본 처리기가 사용된다. 그렇지 않으면 신호가 가로채지고 신호 처리기가 호출된다. 프로세스는 처리기를 생성하지 않고도 두 가지 기본 동작을 지정할 수도 있는데, 신호를 무시(SIG_IGN)하거나 기본 신호 처리기를 사용(SIG_DFL)하는 것이다. SIGKILL과 SIGSTOP 두 신호는 가로채고 처리할 수 없다.[1]

4. 2. `sigreturn()` 시스템 콜

`sigreturn()`은 시그널 핸들러 종료 후 커널로 처리를 반환하는 시스템 콜이다. POSIX 표준에 따라 시그널 마스크 및 스택을 되돌리고, 인터럽트된 프로세스로 복귀한다. 일반적으로 커널이 시그널 핸들러를 호출할 때 래퍼 코드를 준비하고, 핸들러 종료 후 자동으로 `sigreturn()`을 호출하므로 명시적으로 호출할 필요는 없다. 시그널 핸들러가 `longjmp()` 등을 사용하여 시그널 처리 시작 시점과 다른 위치로 점프하는 경우에도 `longjmp()` 등이 `sigreturn()`과 동일한 처리를 수행한다.

4. 3. 슬립 상태와 시그널

시그널을 수신할 수 있도록 슬립 상태에 있는 프로세스는 일반적으로 시그널을 받으면 슬립을 종료한다. 시그널 핸들러 실행이 필요하거나, 기본 동작으로 인해 프로세스가 종료되는 경우에도 마찬가지이다. 이는 UNIX의 모든 프로세스가 스스로 종료되며, 다른 프로세스에 의해 종료될 수 없다는 사양에 따른다. 그러나 종료되는 프로세스는 사용자 모드로 돌아가지 않으므로, 커널 동작을 무시하면 마치 프로세스가 시그널에 의해 "살해된" 것처럼 보인다.

이러한 동작에는 부작용이 있다. 시그널을 수신한 프로세스의 PCB나 커널 스택 등이 스왑 아웃된 경우, 이를 다시 메모리에 읽어들여야 시그널 수신으로 인한 프로세스 종료 처리를 할 수 있다. 커널이 메모리 부족으로 인해 프로세스에 시그널을 보낸 경우, 이 부작용은 메모리 요구량을 일시적으로 증가시킬 수 있다.

위 내용에는 다음과 같은 예외가 있다.

  • 시그널 수신 가능으로 슬립 중인 프로세스에 대한 `SIGSTOP`.
  • 위에 의해 정지되고, 정지 중에 슬립이 종료되지 않은 프로세스에 대한 `SIGCONT`.


어느 경우든, 시그널 수신의 영향은 프로세스가 슬립하고 있는 원인이 변화할 뿐이며, 프로세스가 스케줄되지 않는다는 점은 변함이 없다. 따라서 위에 해당하는 경우에는 시그널을 전송한 프로세스가 전송 대상 프로세스의 상태를 직접 업데이트하고, 그것으로 시그널 수신 처리를 한다.

4. 4. 문제점 및 주의사항

신호는 경합 상태에 취약하다. 신호는 비동기적이므로 신호 처리 루틴을 실행하는 동안 다른 신호(동일한 유형의 신호 포함)가 프로세스에 전달될 수 있다.

`sigprocmask()`를 사용하여 신호 전달을 차단하고 차단을 해제할 수 있다. 차단된 신호는 차단 해제될 때까지 프로세스에 전달되지 않는다. 무시할 수 없는 신호(SIGKILL 및 SIGSTOP)는 차단할 수 없다.[6]

신호는 진행 중인 시스템 호출을 중단시켜 애플리케이션이 비투명 재시작을 관리하도록 할 수 있다. 이 경우, 실행 중인 시스템 콜은 EINTR이라는 에러를 반환하며, 요청한 처리가 시그널 수신에 의해 중단되어 결과를 얻지 못했음을 나타낸다.

시그널 핸들러는 불필요한 부작용을 일으키지 않도록 주의해야 한다. 다음은 구체적인 예시이다.

  • 시그널 핸들러는 재진입 가능한 처리만 수행한다. 특히, `malloc`, `printf`와 같은 비동기 시그널 안전(async-signal-safe)하지 않은 함수를 사용하는 것은 안전하지 않다.[25][26]
  • 재진입 불가능한 처리를 실행하는 경우, 해당 처리가 종료될 때까지 시그널을 마스크하고, 시그널 수신 처리를 지연시킨다.
  • 전역 변수 `errno`의 변경 등, 중단된 처리가 예상하지 못한 변경을 포함하는 처리를 하지 않는다.

5. 하드웨어 예외와의 관계

프로세스 실행 중 하드웨어 예외가 발생할 수 있다. 예를 들어, 0으로 나누기를 시도하거나, TLB 미스를 일으키거나, 페이지 폴트가 발생하는 경우이다. 유닉스 계열 운영체제에서는 하드웨어 예외가 발생하면 컨텍스트를 자동으로 전환하여 커널예외 처리 핸들러 실행을 시작한다. 페이지 폴트와 같은 일부 예외의 경우, 커널은 해당 이벤트를 처리하기에 충분한 정보를 가지고 있으므로 프로세스의 실행을 다시 시작할 수 있다. 그러나 다른 예외에서는 커널이 제대로 처리할 수 없으며, 대신 예외를 발생시킨 프로세스에 예외 처리를 위임해야 한다. 시그널은 이 위임을 위한 메커니즘으로도 작동하며, 커널에서 프로세스로 해당 예외에 대응하는 시그널을 전송한다. 예를 들어, x86 CPU에서 0으로 나누기를 시도하면 ''divide error'' 예외가 발생하고, 커널이 해당 프로세스에 SIGFPE라는 시그널을 전송한다. 마찬가지로, 어떤 프로세스가 자신의 가상 주소 공간 범위를 벗어난 메모리 주소에 접근하려고 하면, 커널은 SIGSEGV 시그널을 전송한다. 하드웨어 예외의 종류는 CPU 아키텍처에 따라 다르므로, 특정 예외가 발생했을 때 어떤 시그널이 전송되는지는 CPU 아키텍처 및 커널 구현에 따라 달라진다.[1]

6. POSIX 시그널

헤더 파일에 정의된 시그널 목록은 다음과 같다(주요 시그널):[10]

신호이식 가능한 번호기본 동작설명
SIGABRT6종료 (코어 덤프)프로세스 중단 신호
SIGALRM14종료알람 시계
SIGBUS없음종료 (코어 덤프)메모리 객체의 정의되지 않은 부분에 대한 접근
SIGCHLD없음무시자식 프로세스가 종료, 중지 또는 계속됨
SIGCONT없음계속중지된 경우 실행을 계속
SIGFPE8종료 (코어 덤프)오류 산술 연산
SIGHUP1종료행업
SIGILL4종료 (코어 덤프)불법적인 명령어
SIGINT2종료터미널 인터럽트 신호
SIGKILL9종료강제 종료 (잡거나 무시할 수 없음)
SIGPIPE13종료읽을 사람이 없는 파이프에 쓰기
SIGPOLL없음종료폴링 가능한 이벤트
SIGPROF없음종료프로파일링 타이머 만료
SIGQUIT3종료 (코어 덤프)터미널 종료 신호
SIGSEGV11종료 (코어 덤프)잘못된 메모리 참조
SIGSTOP없음중지실행 중지 (잡거나 무시할 수 없음)
SIGSYS없음종료 (코어 덤프)잘못된 시스템 호출
SIGTERM15종료종료 신호
SIGTRAP5종료 (코어 덤프)트레이스/브레이크포인트 트랩
SIGTSTP없음중지터미널 중지 신호
SIGTTIN없음중지백그라운드 프로세스가 읽기를 시도함
SIGTTOU없음중지백그라운드 프로세스가 쓰기를 시도함
SIGUSR1없음종료사용자 정의 신호 1
SIGUSR2없음종료사용자 정의 신호 2
SIGURG없음무시대역 외 데이터가 소켓에서 사용 가능함
SIGVTALRM없음종료가상 타이머 만료
SIGXCPU없음종료 (코어 덤프)CPU 시간 제한 초과
SIGXFSZ없음종료 (코어 덤프)파일 크기 제한 초과
SIGWINCH없음무시터미널 창 크기 변경됨


  • '''이식 가능한 번호:''' 대부분의 신호에 대해 해당 신호 번호는 구현에 따라 정의된다. 이 열은 POSIX 표준에 지정된 번호를 나열한다.

  • '''기본 동작 설명:'''[27]
  • '''종료''': 프로세스의 비정상적인 종료. 프로세스는 exit()의 모든 결과와 함께 종료되지만 wait() 및 waitpid()에 사용 가능한 상태는 지정된 신호에 의한 비정상적인 종료를 나타낸다.
  • '''종료 (코어 덤프)''': 프로세스의 비정상적인 종료. 코어 파일 생성과 같은 구현 정의 비정상 종료 작업이 발생할 수 있다.
  • '''무시''': 신호를 무시한다.
  • '''중지''': 프로세스를 중지(또는 일시 중단)한다.
  • '''계속''': 중지된 경우 프로세스를 계속하고, 그렇지 않으면 신호를 무시한다.


아래 표는 Linux x86에서의 시그널 번호이며[28], 다른 OS, 다른 CPU에서는 다를 수 있다. Linux ARM도 시그널 번호는 같다.

시그널 이름설명기본 동작해설Linux x86에서의 시그널 번호
SIGABRT프로세스가 중단됨Aabort()를 프로세스 자신이 실행함으로써 발생한다. 핸들러로 캐치 가능하며 블록할 수 없다. 시그널 핸들러에서 돌아오면 프로세스는 종료된다. 어떤 부정한 상황에 빠졌지만, 일반적인 처리 흐름에서는 종료 전 정리 처리를 할 수 없어, 별도의 문제 해결이 필요한 경우에 사용한다.6
SIGALRMalarm()에 의한 시그널Talarm() 시스템 콜로, 설정한 실제 시간 타이머가 시간 초과되었음을 알린다.14
SIGBUS「정의되지 않은 메모리 영역에 대한 접근」(SUS)에 의한 버스 오류A다음과 같은 부정한 메모리 조작으로 발생한다. 핸들러로 캐치할 수 있지만, 핸들러에서 돌아온 후의 동작은 시스템에 의존한다(일반적으로 프로세스의 종료).7
SIGCHLD자식 프로세스가 종료, 중지(또는 재개)되었다I자식 프로세스의 상태 변화에 따라 발생한다. 부모 프로세스는 무시할 수도 있다.17
SIGCONT정지되어 있으면 재개C프로세스 그룹 참조.18
SIGFPE부동 소수점 예외 -- 「부정한 산술 연산」(SUS)A부동 소수점 연산에서 0으로 나누기나 오버플로우 등이 발생했을 때 발생한다. Signaling NaN이 발생했을 때도 마찬가지다. 또한, 정수 오버플로우 등에서도 발생한다. 핸들러로 캐치할 수 있지만, 적절하게 처리하지 않으면 프로세스가 멈춤(무한 루프)에 빠질 가능성이 있다. (여기서 말하는 적절한 처리는, 시그널 핸들러가 받는 예외 발생 시 레지스터의 내용을 덮어써서 예외가 발생하지 않도록 하는 것이며, 예외 발생 지점의 코드를 분석하여 어떤 레지스터가 사용되었는지 조사하거나, 내용을 덮어써서 계산 결과가 부정확해지지 않는지 판단하는 등의 매우 고도의 대응이 필요하다. 또한, Signaling NaN 이외에는 처리 속행은 거의 불가능)8
SIGHUP행업T원래는 단말의 회선이 끊겼을 때 발생했다. 현재는 가상 터미널을 닫았을 때 해당 터미널에서 시작된 프로세스 그룹에 전송된다. 의 nohup 기능을 사용하면 백그라운드 프로세스가 SIGHUP을 받지 않도록 할 수 있다.1
SIGILL부정 명령어A일반적으로, 명령어가 아닌 메모리 영역으로 점프했을 때 발생한다(콜 스택의 반환 주소가 파괴되었을 때 등). 그 외에 특권 레벨이 높지 않으면 실행할 수 없는 명령을 실행하려고 했을 때 등에도 발생한다.4
SIGINT인터럽트T단말에서 인터럽트 키(일반적으로 CTRL + C)를 눌렀을 때 발생한다.2
SIGKILL강제 종료(kill)Tkill 명령 등으로 명시적으로 발생시킨다. 캐치하거나 무시할 수 없다. 좀비 프로세스는 이미 종료되었으므로 SIGKILL을 받아도 소멸하지 않는다. 슬립 중인 프로세스는 슬립 해제되었을 때 SIGKILL을 받는다. init는 SIGKILL을 무시할 수 있다.9
SIGPIPE읽는 사람이 없는 파이프에 대한 쓰기T13
SIGPOLL*, SIGIO폴링 가능 이벤트T파일 디스크립터에 대해 fcntl() 시스템 콜로 시그널 발생을 지시하면, 폴링 가능 이벤트에 따라 SIGPOLL이 발생한다. 일반적으로 통신 포트에 대응하는 파일 식별자에 사용하며, 완전한 비동기 I/O를 실현한다. 다만, 코드가 복잡해지므로, 최근에는 전용 비동기 I/O 시스템 콜을 사용하는 것이 권장되고 있다.29
SIGPROF*프로파일링 타이머가 시간 초과T프로파일러에서 사용한다. 이 때의 타이머는 프로세스의 전체 실행 시간에 해당한다(CPU 모드에 관계없이 계시한다).27
SIGPWR전원 손실T30
SIGQUIT종료와 코어 덤프A일반적으로, 터미널에서의 종료 키(CTRL + \)로 발생한다.3
SIGSEGV세그멘테이션 오류A페이지 폴트 중 부정한 메모리 접근에 의한 경우에 발생한다. 그러나, 예를 들어 힙 영역의 확장을 SIGSEGV 발생을 받아 온디맨드로 수행하는 라이브러리 등도 있다.11
SIGSTKFLT수치 연산 프로세서에서의 스택 폴트A16
SIGSTOP실행 중단S프로세스 그룹의 실행 중단을 위한 시그널. 캐치도 무시도 할 수 없다. SIGCONT 시그널로 실행을 재개한다.19
SIGSYS*, SIGUNUSED부정 시스템 콜A일반적으로 시스템 콜의 번호나 인수가 부정했을 때는 단순히 오류를 반환하는 것으로 끝나므로, 이 시그널은 거의 사용되지 않는다.31
SIGTERM강제 종료Tkill 명령이 기본적으로 발생하는 시그널. 그러나 이 시그널을 캐치하거나 무시하거나 할 수도 있다.15
SIGTRAP*트레이스/브레이크 포인트에 의한 트랩A어떤 디버깅 기능에서 사용된다(아키텍처에 따라 다르다).5
SIGTSTP터미널로부터의 중단 시그널S포어그라운드의 프로세스 그룹을 실행 중단시킨다(일반적으로, CTRL + Z 누름).20
SIGTTIN백그라운드 프로세스가 터미널에서 읽으려고 했다S백그라운드의 프로세스 그룹이 사용자 입력을 기다리게 되어 중지. 셸 기능을 사용하여 포어그라운드로 하면 입력이 가능하다.21
SIGTTOU백그라운드 프로세스가 터미널에 쓰려고 했다S백그라운드의 프로세스 그룹이 터미널로의 표시를 기다리게 되어 중지. 셸 기능을 사용하여 포어그라운드로 하면 표시가 가능하다.22
SIGURG소켓상에 긴급 데이터(TCP의 대역 외 데이터)가 있다I비동기 I/O 기능에서 사용.23
SIGUSR1사용자 정의 시그널 1TPOSIX에서는 정의되지 않음. 예를 들어 dd 명령이 수신하면 조작의 상황이 표시된다.10
SIGUSR2사용자 정의 시그널 2TPOSIX에서는 정의되지 않음.12
SIGVTALRM*가상 시간을 카운트하는 타이머에 의한 시그널 -- 「가상 타이머의 시간 초과」(SUS)T프로파일러 등에서 사용한다. 이 때의 타이머는 프로세스의 사용자 모드에서의 실행 시간을 계시하는 것. SIGPROF와 조합하면, 프로세스의 커널 모드에서의 실행 시간을 알 수 있다.26
SIGWINCH윈도우 크기 변경 시그널Ixterm 등 크기가 가변적인 제어 터미널에서, 터미널 크기가 변경되었음을 알린다. 텍스트 기반의 GUI를 구현한 소프트웨어에서, 터미널 크기의 변경에 맞춰 UI를 다시 그리는데 사용한다.28
SIGXCPU*CPU 시간 제한을 초과했다A프로세스 실행 시간(슬립했던 시간이나 스케줄링 대기 시간은 제외)이 어떤 값을 초과하면 발생한다.24
SIGXFSZ*파일 크기 제한을 초과했다A파일 크기가 파일 시스템(또는 운영 체제)의 제한을 초과하려고 할 때, 그것을 일으킨 프로세스에 전송된다.25



주: 별표가 붙은 항목은 X/Open System Interfaces (XSI)에 의한 확장을 나타낸다. (SUS)라고 있는 부분은 SUS[27]에 있는 표현의 인용(을 번역한 것).

상술한 외에, 프로세스는 가짜 시그널(번호 0)을 전송할 수도 있다. 이것은 실제로는 시그널을 전송하지 않고 시그널 전송 시 오류 체크를 하며, 예를 들어 대상 프로세스가 존재하는지 여부를 체크하는 데 편리하다.

7. 기타 시그널

POSIX영어 명세에 명시되지 않았지만 다양한 시스템에서 사용되는 시그널은 다음과 같다.


  • '''SIGEMT''': 에뮬레이터 트랩이 발생했을 때 프로세스에 전송된다.
  • '''SIGINFO''': 제어 터미널로부터 상태(정보) 요청을 받았을 때 프로세스에 전송된다.
  • '''SIGPWR''': 시스템에 전원 고장이 발생했을 때 프로세스에 전송된다.
  • '''SIGLOST''': 파일 잠금이 손실되었을 때 프로세스에 전송된다.
  • '''SIGSTKFLT''': 보조 프로세서에서 스택 폴트(스택이 비어 있을 때 팝 또는 스택이 가득 찼을 때 푸시)가 발생했을 때 프로세스에 전송된다.[23] 이는 Linux에서 정의되어 있지만 사용되지 않으며, x87 보조 프로세서 스택 오류는 대신 SIGFPE를 생성한다.[24]
  • '''SIGUNUSED''': 사용되지 않은 시스템 호출 번호로 시스템 호출이 이루어졌을 때 프로세스에 전송된다. 이는 대부분의 아키텍처에서 SIGSYS와 동의어이다.[23]
  • '''SIGCLD''': SIGCHLD와 동의어이다.[23]


단일 UNIX 명세에서는 다음 시그널을 <signal.h>에서 정의해야 한다고 지정하고 있다.

시그널 수신 시 기본 동작은 다음과 같다[27]:

  • T: 프로세스의 비정상 종료. `exit()` 시스템 콜을 실행한 것과 동일한 종료 방식이지만, `wait()` 또는 `waitpid()`로 해당 프로세스의 종료를 기다리고 있던 프로세스에는, 시그널 수신으로 종료되었음을 나타내는 비정상 종료 코드가 반환된다.
  • A: 프로세스의 비정상 종료. 설정되어 있으면 코어 덤프를 생성한다.
  • I: 시그널을 무시한다.
  • S: 프로세스의 실행을 중단(일시 정지)한다.
  • C: 중단되었던 프로세스의 실행을 다시 시작한다. 중단되지 않은 프로세스에서는 무시한다.


아래 표의 시그널 번호는 Linux x86의 경우이며[28], 다른 OS, 다른 CPU에서는 다르다. Linux ARM도 시그널 번호는 같다.

시그널 이름설명기본 동작해설Linux x86에서의
시그널 번호[28]
SIGPWR전원 손실T30
SIGSTKFLT수치 연산 프로세서에서의 스택 폴트A16


참조

[1] 간행물 A Research Unix reader: annotated excerpts from the Programmer's Manual, 1971–1986 https://www.cs.dartm[...]
[2] 웹사이트 C Programming in Plan 9 from Bell Labs https://doc.cat-v.or[...] 2022-01-22
[3] 웹사이트 Termination Signals https://www.gnu.org/[...]
[4] 웹사이트 Job Control Signals https://www.gnu.org/[...]
[5] 웹사이트 Miscellaneous Signals https://www.gnu.org/[...]
[6] 웹사이트 The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition: System Interfaces Chapter 2 https://pubs.opengro[...] 2020-12-20
[7] 웹사이트 signal(7) - Linux manual page https://man7.org/lin[...] 2020-12-20
[8] 웹사이트 signal-safety(7) - Linux manual page https://man7.org/lin[...] 2020-12-20
[9] 웹사이트 The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition: https://pubs.opengro[...] 2020-12-20
[10] 웹사이트 IEEE Std 1003.1-2017 - kill https://pubs.opengro[...] IEEE, Open Group
[11] 웹사이트 signal(7) https://www.kernel.o[...] The Linux Kernel Archives 2009-07-25
[12] 웹사이트 perlipc(1) https://perldoc.perl[...] perldoc.perl.org - Official documentation for the Perl programming language 2013-09-21
[13] 웹사이트 Proper handling of SIGINT and SIGQUIT https://www.cons.org[...] 2012-10-06
[14] 문서 https://manpages.ubuntu.com/manpages/zesty/man2/kill.2.html section NOTES https://manpages.ubu[...]
[15] 웹사이트 SIGKILL init process (PID 1) https://stackoverflo[...]
[16] 웹사이트 Can root kill init process? https://unix.stackex[...]
[17] 웹사이트 Mac Dev Center: What's New in Mac OS X: Mac OS X v10.6 https://developer.ap[...] 2009-08-28
[18] 웹사이트 ioctl - controls a STREAM device https://pubs.opengro[...] "[[The Open Group]]" 2015-06-19
[19] 웹사이트 What is a "segmentation violation"? https://support.micr[...] 2018-11-22
[20] 웹사이트 Syscall User Dispatch – The Linux Kernel documentation https://www.kernel.o[...] 2021-02-11
[21] 웹사이트 getrlimit, setrlimit - control maximum resource consumption https://pubs.opengro[...] "[[The Open Group]]" 2009-09-10
[22] 웹사이트 0001151: Introduce new signal SIGWINCH and functions tcsetsize(), tcgetsize() to get/set terminal window size http://austingroupbu[...] "[[Austin Group]]" 2017-06-19
[23] 웹사이트 signal(7) — Linux manual pages https://manpages.cou[...] 2018-11-22
[24] 웹사이트 Linux 3.0 x86_64: When is SIGSTKFLT raised? https://stackoverflo[...]
[25] 웹사이트 SIG30-C. シグナルハンドラ内では非同期安全な関数のみを呼び出す https://www.jpcert.o[...] "[[JPCERT/CC]]" 2019-02-11
[26] 문서 脚注전항의 링크先記述에는「longjmp()もPOSIXのsiglongjmp()も、シグナルハンドラ内から呼び出してはならない。」とあるが、これは無条件に成立するものではなく、割り込まれた処理に依存するので不正確である。リンク先記述にあるサンプルコードは静的変数へのアクセスがあるためシグナルに対して安全ではないとしているが、適合コード例の他に、シグナルをマスクした上でその静的変数へアクセスすればlongjmp()を残したままにすることができる。POSIX.1-2008 TC2はlongjmp()およびsiglongjmp()を、async-signal-safeではない関数や処理へシグナルが割り込んだ場合のリスクにかかる注意を添えた上でasync-signal-safeな関数リストに追加している。
[27] 웹사이트 signal.h http://pubs.opengrou[...] 2012-07-10
[28] Manpage
[29] 기술보고서 A Research Unix reader: annotated excerpts from the Programmer's Manual, 1971–1986 http://www.cs.dartmo[...]



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com