SIGINT는 SIGTERM, SIGQUIT 및 SIGKILL과 같은 다른 종료 신호와 어떤 관련이 있습니까?


103

POSIX 시스템에서 종료 신호는 일반적으로 다음 순서를 갖습니다 (많은 MAN 페이지 및 POSIX 사양에 따라).

  1. SIGTERM-프로세스를 종료하도록 정중하게 요청합니다. 정상적으로 종료되고 모든 리소스 (파일, 소켓, 자식 프로세스 등)를 정리하고 임시 파일을 삭제하는 등의 작업을 수행합니다.

  2. SIGQUIT-더 강력한 요청. 비정상적으로 종료되고, 절대적으로 정리가 필요한 리소스를 정리하지만 임시 파일을 삭제하지 않고 디버그 정보를 어딘가에 쓸 수도 있습니다. 일부 시스템에서는 코어 덤프도 기록됩니다 (앱에서 신호를 포착했는지 여부에 관계없이).

  3. SIGKILL-가장 강력한 요청. 프로세스는 아무것도하지 않아도되지만 시스템은 그게 좋든 싫든 프로세스를 정리합니다. 대부분 코어 덤프가 작성됩니다.

SIGINT는 그 그림에 어떻게 들어 맞습니까? CLI 프로세스는 일반적으로 사용자가 CRTL + C를 누르면 SIGINT에 의해 종료되지만, 백그라운드 프로세스는 KILL 유틸리티를 사용하여 SIGINT에 의해 종료 될 수도 있습니다. 사양이나 헤더 파일에서 볼 수없는 것은 SIGINT가 SIGTERM보다 다소 강력하거나 SIGINT와 SIGTERM간에 차이가 있는지 여부입니다.

최신 정보:

지금까지 찾은 종료 신호에 대한 가장 좋은 설명은 GNU LibC 문서에 있습니다. SIGTERM과 SIGQUIT 사이에 의도 된 차이가 있음을 잘 설명합니다.

SIGTERM에 대해 다음과 같이 말합니다.

프로그램을 종료하도록 정중하게 요청하는 것은 정상적인 방법입니다.

그리고 SIGQUIT에 대해 다음과 같이 말합니다.

[...] 프로그램 오류 신호처럼 프로세스가 종료 될 때 코어 덤프를 생성합니다. 이를 사용자가 "감지 한"프로그램 오류 상태로 생각할 수 있습니다. [...] 특정 종류의 정리는 SIGQUIT를 처리 할 때 생략하는 것이 가장 좋습니다. 예를 들어 프로그램이 임시 파일을 만드는 경우 임시 파일을 삭제하여 다른 종료 요청을 처리해야합니다. 그러나 SIGQUIT는이를 삭제하지 않는 것이 좋습니다. 그래야 사용자가 코어 덤프와 함께이를 검사 할 수 있습니다.

그리고 SIGHUP도 충분히 설명되어 있습니다. SIGHUP는 실제로 종료 신호가 아닙니다. 사용자와의 "연결"이 끊어 졌음을 의미합니다. 따라서 앱은 사용자가 추가 출력 (예 : stdout / stderr 출력)을 읽을 것으로 기대할 수 없으며 더 이상 사용자. 대부분의 앱은 종료하는 것이 좋습니다. 이론적으로 앱은 SIGHUP가 수신 될 때 데몬 모드로 들어가고 이제 백그라운드 프로세스로 실행되어 구성된 로그 파일에 출력을 기록하도록 결정할 수 있습니다. 이미 백그라운드에서 실행중인 대부분의 데몬의 경우 SIGHUP는 일반적으로 구성 파일을 다시 검사해야 함을 의미하므로 구성 파일을 편집 한 후 백그라운드 프로세스로 보냅니다.

그러나이 페이지에는 CRTL + C에서 보낸 것 외에는 SIGINT에 대한 유용한 설명이 없습니다. SIGTERM과 다른 방식으로 SIGINT를 처리하는 이유가 있습니까? 그렇다면 이유는 무엇이며 취급 방법은 어떻게 다를까요?


1
좋은 질문. 나는 역사적인 유닉스 균열 중 일부가 대답에 관여 할 것이라고 생각합니다.
Alex B

이 질문은 오래되었다는 것을 알고 있지만 (Linux) OS에 대한 광범위한 신호 목록을 위해 여기에 온 경우 sudo fuser -l명령 프롬프트 에 입력하여 찾을 수 있습니다 . 나를 위해 이것은 다음과 같은 내용을 제공합니다.HUP INT QUIT ILL TRAP ABRT IOT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR SYS UNUSED
Nick Bull

3
또한 kill -l신호 목록을 시도 하십시오.
AAAfarmclub

답변:


88

SIGTERM 및 SIGKILL은 범용 "이 프로세스 종료"요청을위한 것입니다. SIGTERM (기본값) 및 SIGKILL (항상)은 프로세스를 종료합니다. SIGTERM은 프로세스에 의해 잡히거나 (예를 들어 원할 경우 자체 정리를 수행 할 수 있도록) 완전히 무시 될 수 있습니다. 그러나 SIGKILL은 포착하거나 무시할 수 없습니다.

SIGINT 및 SIGQUIT는 터미널의 요청을 위해 특별히 고안되었습니다. 특정 입력 문자를 할당하여 이러한 신호를 생성 할 수 있습니다 (터미널 제어 설정에 따라 다름). SIGINT에 대한 기본 동작은 SIGTERM에 대한 기본 동작과 SIGKILL에 대한 변경 불가능한 동작과 동일한 종류의 프로세스 종료입니다. SIGQUIT의 기본 작업은 프로세스 종료이기도하지만 코어 덤프 생성과 같은 추가 구현 정의 작업이 발생할 수 있습니다. 필요한 경우 프로세스에서 포착하거나 무시할 수 있습니다.

당신이 말했듯이 SIGHUP는 종료 신호가 아닌 터미널 연결이 끊어 졌음을 나타 내기위한 것입니다. 그러나 다시, SIGHUP의 기본 동작 (프로세스가이를 포착하거나 무시하지 않는 경우)은 SIGTERM 등과 같은 방식으로 프로세스를 종료하는 것입니다.

POSIX 정의 signal.h에는 다양한 신호와 기본 동작 및 목적이 나열된 표가 있으며 일반 터미널 인터페이스 장에는 터미널 관련 신호에 대한 자세한 내용이 포함되어 있습니다.


10
이것이 핵심 포인트입니다. SIGINT 및 SIGQUIT는 프로그램이 실행되는 동안 단일 문자를 사용하여 터미널에서 생성 될 수 있습니다. 다른 신호는 다른 프로그램에 의해 생성되어야합니다 (예 : kill 명령). SIGINT는 SIGQUIT보다 덜 폭력적입니다. 후자는 코어 덤프를 생성합니다. SIGKILL은 트랩 될 수 없습니다. 연결이 끊어지면 (창이 닫히는 등) SIGHUP가 생성됩니다. 그래서 그들은 모두 다른 의미를 가지고 있습니다.
Jonathan Leffler

TTY Demystified 에는 신호가 커널의 tty 하위 시스템과 상호 작용하는 방법에 대한 이해하기 쉬운 정보가 있습니다. 답변에 컨텍스트를 추가합니다.
Daniel Näslund

2
사양이 정확하지 않은 것처럼 보이지만 내 이해는 SIgint가 프로그램이 반드시 종료하는 것이 아니라 현재 작업을 중지하도록 요청한다는 것입니다. 디자인 된 프로그램의 경우 종료를 의미하는 실행 당 하나의 작업 만 수행하지만 일종의 읽기 평가 인쇄 루프가있는 대화 형 프로그램의 경우 현재 평가를 포기하고 사용자 입력 읽기로 돌아갈 수 있습니다. 나는 sigint에서 덜한다고 생각합니다.
bdsl

재부팅 중에 어떤 신호가 전송됩니까?
Dan Dascalescu

10

DarkDust는 많은 신호가 동일한 결과를 나타내지 만 프로세스는 각 신호가 생성되는 방식을 구별하여 서로 다른 작업을 연결할 수 있다고 지적했습니다. FreeBSD 커널 소스 코드 (kern_sig.c)를 살펴보면 두 신호가 같은 방식으로 처리되고 프로세스를 종료하고 모든 스레드로 전달되는 것을 알 수 있습니다.

SA_KILL|SA_PROC,             /* SIGINT */
SA_KILL|SA_PROC,             /* SIGTERM */

9

man 7 signal

이것은 Linux 신호 정보에 대해 자주 살펴보고 싶은 Linux man-pages 프로젝트 의 편리한 비표준 맨 페이지입니다 .

버전 3.22는 다음과 같은 흥미로운 사항을 언급합니다.

SIGKILL 및 SIGSTOP 신호는 포착, 차단 또는 무시할 수 없습니다.

테이블을 포함합니다.

Signal     Value     Action   Comment
----------------------------------------------------------------------
SIGHUP        1       Term    Hangup detected on controlling terminal
                              or death of controlling process
SIGINT        2       Term    Interrupt from keyboard
SIGQUIT       3       Core    Quit from keyboard
SIGILL        4       Core    Illegal Instruction
SIGABRT       6       Core    Abort signal from abort(3)
SIGFPE        8       Core    Floating point exception
SIGKILL       9       Term    Kill signal
SIGSEGV      11       Core    Invalid memory reference
SIGPIPE      13       Term    Broken pipe: write to pipe with no
                              readers
SIGALRM      14       Term    Timer signal from alarm(2)
SIGTERM      15       Term    Termination signal
SIGUSR1   30,10,16    Term    User-defined signal 1
SIGUSR2   31,12,17    Term    User-defined signal 2
SIGCHLD   20,17,18    Ign     Child stopped or terminated
SIGCONT   19,18,25    Cont    Continue if stopped
SIGSTOP   17,19,23    Stop    Stop process
SIGTSTP   18,20,24    Stop    Stop typed at tty
SIGTTIN   21,21,26    Stop    tty input for background process
SIGTTOU   22,22,27    Stop    tty output for background process

ActionSIGQUIT에는 action Core과 SIGINT 가 있기 때문에 SIGQUIT 와 SIGQUIT를 구별 하는 신호를 요약 Term합니다.

작업은 동일한 문서에 설명되어 있습니다.

The entries in the "Action" column of the tables below specify the default disposition for each signal, as follows:

Term   Default action is to terminate the process.

Ign    Default action is to ignore the signal.
Core   Default action is to terminate the process and dump core (see core(5)).
Stop   Default action is to stop the process.
Cont   Default action is to continue the process if it is currently stopped.

커널의 관점에서 SIGTERM과 SIGINT의 차이점을 볼 수 없습니다 Term. 둘 다 동작이 있고 둘 다 잡힐 수 있기 때문입니다. 그것은 단지 "일반적인 사용 관례 구별"인 것 같습니다 :

  • SIGINT는 터미널에서 CTRL-C를 수행 할 때 발생합니다.
  • SIGTERM은 kill

일부 신호는 ANSI C이고 다른 신호는 그렇지 않습니다.

상당한 차이점은 다음과 같습니다.

  • SIGINT 및 SIGTERM은 ANSI C이므로 더 이식 가능합니다.
  • SIGQUIT 및 SIGKILL은

C99 초안 N1256 의 "7.14 신호 처리"섹션에 설명되어 있습니다 .

  • 대화 형주의 신호의 SIGINT 수신
  • SIGTERM 프로그램에 전송 된 종료 요청

따라서 SIGINT는 대화 형 Ctrl + C를위한 좋은 후보입니다.

POSIX 7

POSIX 7은 signal.h헤더가 있는 신호를 문서화합니다 . https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html

이 페이지에는 또한 우리가 이미 본 것들 중 일부를 언급하는 다음 관심 표가 있습니다 man 7 signal.

Signal    Default Action   Description
SIGABRT   A                Process abort signal.
SIGALRM   T                Alarm clock.
SIGBUS    A                Access to an undefined portion of a memory object.
SIGCHLD   I                Child process terminated, stopped,
SIGCONT   C                Continue executing, if stopped.
SIGFPE    A                Erroneous arithmetic operation.
SIGHUP    T                Hangup.
SIGILL    A                Illegal instruction.
SIGINT    T                Terminal interrupt signal.
SIGKILL   T                Kill (cannot be caught or ignored).
SIGPIPE   T                Write on a pipe with no one to read it.
SIGQUIT   A                Terminal quit signal.
SIGSEGV   A                Invalid memory reference.
SIGSTOP   S                Stop executing (cannot be caught or ignored).
SIGTERM   T                Termination signal.
SIGTSTP   S                Terminal stop signal.
SIGTTIN   S                Background process attempting read.
SIGTTOU   S                Background process attempting write.
SIGUSR1   T                User-defined signal 1.
SIGUSR2   T                User-defined signal 2.
SIGTRAP   A                Trace/breakpoint trap.
SIGURG    I                High bandwidth data is available at a socket.
SIGXCPU   A                CPU time limit exceeded.
SIGXFSZ   A                File size limit exceeded.

BusyBox 초기화

BusyBox의 1.29.2 기본 reboot명령은 SIGTERM을 프로세스로 보내고 1 초 동안 휴면 한 다음 SIGKILL을 보냅니다. 이것은 다른 배포판에서 일반적인 규칙 인 것 같습니다.

다음을 사용하여 BusyBox 시스템을 종료 할 때 :

reboot

init 프로세스에 신호를 보냅니다.

그런 다음 초기화 신호 처리기가 다음을 호출합니다.

static void run_shutdown_and_kill_processes(void)
{
    /* Run everything to be run at "shutdown".  This is done _prior_
     * to killing everything, in case people wish to use scripts to
     * shut things down gracefully... */
    run_actions(SHUTDOWN);

    message(L_CONSOLE | L_LOG, "The system is going down NOW!");

    /* Send signals to every process _except_ pid 1 */
    kill(-1, SIGTERM);
    message(L_CONSOLE, "Sent SIG%s to all processes", "TERM");
    sync();
    sleep(1);

    kill(-1, SIGKILL);
    message(L_CONSOLE, "Sent SIG%s to all processes", "KILL");
    sync();
    /*sleep(1); - callers take care about making a pause */
}

터미널에 인쇄합니다.

The system is going down NOW!
Sent SIGTERM to all processes
Sent SIGKILL to all processes

여기에 최소한의 구체적인 예가 있습니다.

커널에서 보낸 신호


8

sigint 대 sigterm 을 Google에서 빠르게 검색 한 결과 , 둘 사이에 의도 된 유일한 차이점은 바로 가기 키 또는에 대한 명시 적 호출에 의해 시작되었는지 여부 kill입니다.

결과적으로, 예를 들어 sigint를 가로 채서 키보드 단축키로 전송되었을 가능성이 있음을 알면서 특수한 작업을 수행 할 수 있습니다. 아마도 죽는 대신 화면이나 무언가를 새로 고칠 수 있습니다 (사람들 ^C이 프로그램을 죽일 것으로 예상 하므로 권장하지 않습니다 .

나는 또한 ^\sigquit를 보내야한다는 것을 배웠고 , 내가 나 자신을 사용하기 시작할 수도있다. 매우 유용 해 보입니다.


3

kill(시스템 호출과 유틸리티를 모두 사용 하면 권한이 주어지면 거의 모든 신호를 모든 프로세스에 보낼 수 있습니다. 프로세스는 신호가 어떻게 생겼는지와 신호를 보낸 사람을 구분할 수 없습니다.

즉, SIGINT는 실제로 Ctrl-C 인터럽트를 신호하는 반면 SIGTERM은 일반 터미널 신호입니다. 차단하거나 처리 할 수없는 신호가 있다는 유일한 예외를 제외하고는 신호가 "더 강력"하다는 개념은 없습니다 (맨 페이지에 따르면 SIGKILL 및 SIGSTOP).

신호는 수신 프로세스가 신호를 처리하는 방법 (및 해당 신호에 대한 기본 동작이 무엇인지)과 관련하여 다른 신호보다 "더 강력"할 수 있습니다. 예를 들어, 기본적으로 SIGTERM과 SIGINT는 모두 종료로 이어집니다. 그러나 SIGTERM을 무시하면 SIGINT가 여전히 수행하는 동안 프로세스를 종료하지 않습니다.


0

몇 가지 신호를 제외하고 신호 핸들러는 다양한 신호를 포착하거나 신호 수신시 기본 동작을 수정할 수 있습니다. 자세한 내용은 signal(7)man 페이지를 참조하십시오.


예,하지만 단문의 "의미"를 모르는 경우 신호를 잡는 것은 무의미합니다. 응용 프로그램에서 무엇을해야하는지 알 수 없기 때문입니다. GNU C는 예를 들어 SIGQUIT와 SIGTERM의 차이점을 설명합니다. 그러나 SIGINT에 대한 정보는 거의 제공하지 않습니다. gnu.org/s/libc/manual/html_node/Termination-Signals.html
Mecki

" SIGINT("프로그램 인터럽트 ") 신호는 사용자가 INTR 문자 (일반적으로 C-c)를 입력 할 때 전송됩니다 ." "SIGINT 2 Term Interrupt from keyboard"Ctrl-C를 누르면 SIGINT전송됩니다. 프로세스는 일반적으로 종료됩니다. 무엇을 더 줄까요?
Ignacio Vazquez-Abrams

프로그래머가 ctrl-c, 즉 메시지의 의미를 누를 때 사용자가 가질 것이라고 가정해야하는 의도에 대한 설명이있을 수 있습니다. 예를 들어 HTTP 사양은 사용자가 GET 요청을 보낼 때 서버가 응답을 다시 보내는 것 외에는 아무 작업도 수행하기를 원한다고 가정해서는 안된다는 것을 분명히합니다.
bdsl
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.