SIGINT는 SIGTERM, SIGQUIT 및 SIGKILL과 같은 다른 종료 신호와 어떤 관련이 있습니까?
POSIX 시스템에서 종료 신호는 일반적으로 다음 순서를 갖습니다 (많은 MAN 페이지 및 POSIX 사양에 따라).
SIGTERM-프로세스를 종료하도록 정중하게 요청합니다. 정상적으로 종료되고 모든 리소스 (파일, 소켓, 자식 프로세스 등)를 정리하고 임시 파일을 삭제하는 등의 작업을 수행합니다.
SIGQUIT-더 강력한 요청. 비정상적으로 종료되고, 절대적으로 정리가 필요한 리소스를 정리하지만 임시 파일을 삭제하지 않고 디버그 정보를 어딘가에 쓸 수도 있습니다. 일부 시스템에서는 코어 덤프도 기록됩니다 (앱에서 신호를 포착했는지 여부에 관계없이).
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를 처리하는 이유가 있습니까? 그렇다면 이유는 무엇이며 취급 방법은 어떻게 다를까요?
SIGTERM 및 SIGKILL은 범용 "이 프로세스 종료"요청을위한 것입니다. SIGTERM (기본값) 및 SIGKILL (항상)은 프로세스를 종료합니다. SIGTERM은 프로세스에 의해 잡히거나 (예를 들어 원할 경우 자체 정리를 수행 할 수 있도록) 완전히 무시 될 수 있습니다. 그러나 SIGKILL은 포착하거나 무시할 수 없습니다.
SIGINT 및 SIGQUIT는 터미널의 요청을 위해 특별히 고안되었습니다. 특정 입력 문자를 할당하여 이러한 신호를 생성 할 수 있습니다 (터미널 제어 설정에 따라 다름). SIGINT에 대한 기본 동작은 SIGTERM에 대한 기본 동작과 SIGKILL에 대한 변경 불가능한 동작과 동일한 종류의 프로세스 종료입니다. SIGQUIT의 기본 작업은 프로세스 종료이기도하지만 코어 덤프 생성과 같은 추가 구현 정의 작업이 발생할 수 있습니다. 필요한 경우 프로세스에서 포착하거나 무시할 수 있습니다.
당신이 말했듯이 SIGHUP는 종료 신호가 아닌 터미널 연결이 끊어 졌음을 나타 내기위한 것입니다. 그러나 다시, SIGHUP의 기본 동작 (프로세스가이를 포착하거나 무시하지 않는 경우)은 SIGTERM 등과 같은 방식으로 프로세스를 종료하는 것입니다.
POSIX 정의 signal.h
에는 다양한 신호와 기본 동작 및 목적이 나열된 표가 있으며 일반 터미널 인터페이스 장에는 터미널 관련 신호에 대한 자세한 내용이 포함되어 있습니다.
DarkDust는 많은 신호가 동일한 결과를 나타내지 만 프로세스는 각 신호가 생성되는 방식을 구별하여 서로 다른 작업을 연결할 수 있다고 지적했습니다. FreeBSD 커널 소스 코드 (kern_sig.c)를 살펴보면 두 신호가 동일한 방식으로 처리되고 프로세스를 종료하고 모든 스레드로 전달되는 것을 알 수 있습니다.
SA_KILL|SA_PROC, /* SIGINT */
SA_KILL|SA_PROC, /* SIGTERM */
Google에서 sigint 대 sigterm 을 빠르게 검색 한 결과 , 둘 사이에 의도 된 유일한 차이점은 바로 가기 키 또는에 대한 명시적인 호출에 의해 시작되었는지 여부 kill
입니다.
결과적으로, 예를 들어 sigint를 가로 채서 키보드 단축키로 전송되었을 가능성이 있음을 알면서 특수한 작업을 수행 할 수 있습니다. 아마도 죽는 대신 화면이나 무언가를 새로 고칠 수 있습니다 (사람들 ^C
이 프로그램을 죽일 것으로 예상 하므로 권장하지 않습니다 .
나는 또한 ^\
sigquit를 보내야한다는 것을 배웠습니다 . 매우 유용 해 보입니다.
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
which summarizes signal Action
that distinguishes e.g. SIGQUIT from SIGQUIT, since SIGQUIT has action Core
and SIGINT Term
.
The actions are documented in the same document:
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.
I cannot see any difference between SIGTERM and SIGINT from the point of view of the kernel since both have action Term
and both can be caught. It seems that is just a "common usage convention distinction":
- SIGINT is what happens when you do CTRL-C from the terminal
- SIGTERM is the default signal sent by
kill
Some signals are ANSI C and others not
A considerable difference is that:
- SIGINT and SIGTERM are ANSI C, thus more portable
- SIGQUIT and SIGKILL are not
They are described on section "7.14 Signal handling " of the C99 draft N1256:
- SIGINT receipt of an interactive attention signal
- SIGTERM a termination request sent to the program
which makes SIGINT a good candidate for an interactive Ctrl + C.
POSIX 7
POSIX 7 documents the signals with the signal.h
header: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html
This page also has the following table of interest which mentions some of the things we had already seen in 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 init
BusyBox's 1.29.2 default reboot
command sends a SIGTERM to processes, sleeps for a second, and then sends SIGKILL. This seems to be a common convention across different distros.
When you shutdown a BusyBox system with:
reboot
it sends a signal to the init process.
Then, the init signal handler ends up calling:
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 */
}
which prints to the terminal:
The system is going down NOW!
Sent SIGTERM to all processes
Sent SIGKILL to all processes
Here is a minimal concrete example of that.
Signals sent by the kernel
- SIGKILL:
- OOM killer: What is RSS and VSZ in Linux memory management
Using kill
(both the system call and the utility` you can send almost any signal to any process, given you've got the permission. A process cannot distinguish how a signal came to life and who has sent it.
That being said, SIGINT really is meant to singal the Ctrl-C interruption, while SIGTERM is the general terminal signal. There is no concept of a signal being "more forceful", with the only exception that there are signals that cannot be blocked or handled (SIGKILL and SIGSTOP, according to the man page).
A signal can only be "more forceful" than another signal with respect to how a receiving process handles the signal (and what the default action for that signal is). For example, by default, both SIGTERM and SIGINT lead to termination. But if you ignore SIGTERM then it will not terminate your process, while SIGINT still does.
With the exception of a few signals, signal handlers can catch the various signals, or the default behavior upon receipt of a signal can be modified. See the signal(7)
man page for details.
'Programing' 카테고리의 다른 글
Mongodb : 사용하기 전에 알아야 할 사항은 무엇입니까? (0) | 2020.09.02 |
---|---|
추상 필드가 아닌 이유는 무엇입니까? (0) | 2020.09.02 |
std :: initializer_list가 기본 제공 언어가 아닌 이유는 무엇입니까? (0) | 2020.09.02 |
Haskell 오프라인 문서? (0) | 2020.09.02 |
java.lang.String에서 java.io.InputStream을 어떻게 얻을 수 있습니까? (0) | 2020.09.02 |