이 중에서 SIGHUP은 SIGHangUp으로 exit명령어를 실행시 모든 프로세스에게 전달되어 종료시키는 역할을 한다. 이전 포스트에서 언급했었던 nohup의 경우 이 SIGHUP 신호를 막는 것이다.
Signal Types
SIGABRT : generated by calling the abort function abort함수를 실행시 프로세스를 종료시키기 위해 보내는 signal
SIGALRM : generated when a timer set with the alarm expires. 지정된 timer의 만료시 보내는 signal
SIGCHLD : whenever a process terminates or stops, the signal is sent to the parent. child process가 종료되거나 중단되는 경우 parent process에게 보내는 signal
SIGCONT : this signal sent to a stopped process when it is continued. 중단된 process가 동작을 시작하도록 보내는 signal
SIGFPE : signals an arithmetic exception, such as divide-by-0, floating point overflow, and so on 0으로 나누거나, 부동소수점 overflow가 발생하는 등 계산적 오류시 보내는 signal
SIGILL : indicates that the process has executed an illegal hardware instruction. 잘못된 하드웨어 명령을 내렸을 때 보내는 signal
SIGINT : generated by the terminal driver when we type the interrupt key and sent to all processes in the foreground process group. Ctrl+C와 같은 종료키를 눌렀을 때, foreground로 동작하는 모든 process에게 interrupt하도록 보내는 signal
강조하지만 signal은 kernel이 process에게 보내준다.
※ SIGINT와 SIGQUIT라는 유사한 signal이 있는데 이 둘의 차이는 SIGINT는 coredump를 남기지 않고, SIGQUIT는 coredump를 남긴다는 점이다.
SIGKILL : can’t be caught or ignored. a sure way to kill any process. kill 명령어에 -9 옵션을 주면 보내는 무시할 수 없는 종료 signal, 일반적으로 SIGTERM으로 종료할 수 없을 때 사용
SIGPIPE : if we write to a pipeline but the reader has terminated, SIGPIPE is generated. -- pipe RPC에 대한 내용 이후에 알아보자
SIGSEGV : indicates that the process has made an invalid memory reference. (→ core dumped) 메모리 참조 오류 발생시 보내는 signal
SIGTERM : the termination signal sent by the kill(1) command by default. kill(1)명령어를 기본으로 실행하면 보내는 종료 signal
SIGTSTP : Cntl-Z from the terminal driver which is sent to all processes in the foreground process group. Ctrl + Z를 통해 모든 foreground process 에게 중단하도록 보내는 signal
SIGUSR1 : user defined signal 1 사용자 정의 signal
SIGUSR2 : user defined signal 2 사용자 정의 signal
SIGSTOP : job control signal. can’t be caught or ignored. process의 동작을 잠시 중단하도록 보내는 signal
stop이나 사용자 정의 signal등의 일부 signal을 제외하고 나머지 signal은 대부분 default action이 종료이다.
Signal Lifecycle
signal is a software notification to a process of an event. signal은 process에 event가 발생하였다는 비동기적 알림이다
signal is generated when the event that causes the signal occurs. signal이 생성되고
signal is delivered when the process takes action based on that signal. signal이 process로 전달된다
The lifetime of a signal is the interval between its generation and its delivery.
signal that has been generated but not yet delivered is said to be pending. signal이 전달되지 못하고 pending되는 경우가 있다.
process catches a signal if it executes a signal handler when the signal is delivered. process가 전달되는 signal을 catch하지 못하면 default action으로 종료되나, catch하게 되면 사전에 정의된 signal handler를 interrupt 방식으로 실행한다.
program installs a signal handler by calling sigaction with the name of a user-written function. 해당 signal handler를 등록하는 것을 install이라고 하고, sigaction system call을 통해 install을 진행한다.
Normal and abnormal termination
#include <sys/wait.h>
void
pr_exit(int status)
{
if (WIFEXITED(status))
printf("normal termination, exit status = %d\n", WEXITSTATUS(status));
else if (WIFSIGNALED(status))
printf("abnormal termination, signal number = %d%s\n",WTERMSIG(status),
#ifdef WCOREDUMP
WCOREDUMP(status) ? " (core file generated)" : "");
#else
"");
#endif
else if (WIFSTOPPED(status))
printf("child stopped, signal number = %d\n", WSTOPSIG(status));
}
위 코드는 정상종료 혹은 비정상 종료를 판별하는 코드이다.
child process가 종료되면 parent process의 wait(&status)를 통해 exit status를 받게된다.
stop signal을 통해서 child process가 잠시 중단되더라도 parent의 wait로 exit status가 전달되는데, 이 때는 WIFSTOPPED를 통해서 child가 stop되었음을 확인할 수 있다.
WEXITSTATUS를 통해 exit status의 값을 확인할 수 있고, 만약 WIFSIGNALED를 통해 signal로 인해 종료된 것임을 확인하면 WTERMSIG를 통해서 signal number를 확인할 수 있다.
signal을 받고 종료하였을 때, coredump를 하였나 확인하기 위해서 WCOREDUMP를 사용할 수 있다.
Signal handling
signal을 받으면 다음 세 가지 중 하나를 하게 된다.
Ignore action (무시) but two signals can never be ignored: SIGKILL and SIGSTOP SIGKILL과 SIGSTOP은 무시하지 못함
User-defined action. (사용자 정의) To do this, we tell the kernel to call a function of ours whenever the signal occurs. (signal handler) process가 signal을 catch하여 종료 대신 사용자가 정의한 signal handler를 실행하고 프로세스를 재개한다. Note that the two signals SIGKILL and SIGSTOP can't be caught. SIGKILL과 SIGSTOP은 catch하지 못함
Default action. (SIG 고유 default action) Every signal has a default action, The default action is normally to terminate process 다음 5개를 제외한 대부분의 경우 default action이 프로세스 종료 default action : SIGSTOP(stop), SIGTSTP(stop), SIGCONT(continue), SIGUSR1(ignore), SIGUSR2(ignore)
Signal handling : User-defined action
위 그림은 어떤 process q가 실행 중에 signal을 받는 상황이다.
process가 signal을 catch하게 되면, signal handler를 실행하고 handler가 끝나면 다시 원래 위치로 돌아와서 q process를 실행한다.
signal을 catch하고 handler를 실행하고 돌아오는 동안 process가 실행하지 않는다. 이와 같은 방식이 interrupt한 방식이다.
signal handler가 종료하였을 때, process가 signal을 catch하였던 위치로 돌아가 process를 재개한다.
asynchronous하기 때문에, signal handler에서 process가 signal을 catch하여 실행된 위치가 어딘지는 모른다.