본문 바로가기
컴퓨터 기초/운영체제 실습

[운영체제 실습] 11.시그널

by 인생여희 2020. 7. 3.

시그널의 개념 : 시그널은 프로세스에게 뭔가 발생했음을 알리는 간단한 메시지를 비동기적으로 보내는 것이다.

1 시그널의 발생 : 시그널은 소프트웨어 인터럽트다. 시그널은 비동기적으로 발생하며, 유닉스 운영체제가 프로세스에 전달한다.

예)

*0으로 나누기처럼 프로그램에서 예외 상황이 일어나는 경우

*사용자가 ctrl + c 같은 인터럽트를 입력한 경우

*프로세스가 kill 함수와 같이 시그널을 보낼 수 있는 함수를 사용해 다른 프로세스에 시그널을 보내는 경우

 

 

2.시그널 처리방법

*프로세스가 받은 시그널에 따라 기본 동작을 수행한다. 각 시그널에는 기본 동작이 지정되어 있다. 대부분 시그널의 기본 동작은 프로세스를 종료하는 것이다. 

*프로세스가 받은 시그널을 무시한다. 프로세스가 시그널을 무시하기로 지정하면 유닉스는 프로세스에 시그널을 전달하지 않는다.

*프로세스는 시그널의 처리를 위해 미리 함수를 지정해 놓고, 시그널을 바등면 해당 함수를 호출 해서 처리한다.(시그널 처리를 위해 지정하는 함수를 시그널 핸들러라고 한다.)

*프로세스는 특정 부분이 실행되는 동안 시그널이 발생하지 않도록 블록할 수 있다. 블록된 시그널은 큐에 쌓여 있다가 시그널 블록이 해제되면 전달된다.

 

2.시그널 종류

 

시그널은 <signal.h> 파일에 정의되어 있습니다. 현재 정의되어 있는 시그널은 아래와 같습니다. 기본 처리 중 종료는 프로세스가 그냥 종료되는 것이고, 코어 덤프는 코어 파일을 만들고 종료하는 것입니다.

 

[root@dev]# kill -l

 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP

 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1

11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM

16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP

21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ

26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR

31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3

38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8

43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13

48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12

53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7

58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2

63) SIGRTMAX-1  64) SIGRTMAX

 

#.kill 함수

#.부모프로세스와 자신에게 시그널을 보내고 기본 처리 동작을 확인하기

 

예제 

결과

 

 

프로세스가 시그널을 받을때 수행하는 기본적인 처리는 대부분 프로세스를 종료하는 것이다. 만일 프로세스를 종료하기 전에 처리할 작업이 남아 있거나, 특정 시그널에 대해 종료하고 싶지 않으면 시그널을 수행할 함수를 지정하면 된다.

 

 

시그널 핸들러 함수 형식

#include <signal.h>

void ( *signal (int sig, void(*func)(int)) )(int);

 

sig : 시그널 핸들러로 처리하려는 시그널

func : 시그널 핸들러의 함수명

리턴값 : 시그널 핸들러의 주소.

 

#.signal 함수 사용하기

 

예제

결과

 

sigset 함수— 시그널 처리 함수를 변경한다.

 

매개 변수

sig : 시그널 번호

disp : 시그널 처리 함수

설명 : 이 함수는 시그널 처리 함수를 변경한다. 인자 disp은 SIG_DFL, SIG_IGN, 혹은 시그널 처리 함수이다.

반환 값 : 시그널이 블록되어있다면 SIG_HOLD를 반환한다. 그렇지 않다면 SIG_ERR를 반환한다.

 

 

 

 

===================  실습 2 ====================

 

 

 #.시그널을 사용하는 이유?

 

 *비동기적인 사건의 발생을 통지하기 위해서.

 예)SIGALARM

 

 *사건을 동기화 시키기 위해서

 예)SIGKILL, SIGSEGV

 

#.언제쓰이나?

- 알람

- 0으로 나눌때

- ctrl + c

- 자식프로세스가 종료될때

 

 #.shell 에서 시그널 사용

 예)# kill -SIGKILL 100

 100번 프로세스로 SIGKILL 시그널이 전달되고, 해당 프로세스는 강제로 종료된다.

 (참고)자기가 권한을 가지고 있는 프로세스에 대해서만 시그널을 보낼 수 있음.

 

 #.시그널을 받았을 때

 *시그널을 처리하기 위한 등록된 함수를 호출 한다.

 *무시한다.

 *무시하지도 않고, 함수 호출도 하지 않는다.

  - 프로세스가 죽음.

  - 프로세스가 중단됨.

  - 무시됨.

 

 #.catch

 *시그널을 사용할려면 시그널을 catch해야한다. catch 못하면 시그널을 제어할 수 없다.

 

예제

결과

 

프로그램을 종료시키기 위해서  Ctrl+C  입력하는 것으로, 이 키를 입력하면 해당 프로세스에 SIGINT가 전달이 되어서 프로세스가 종료가 된다

 

 

#.시그널이 전달되면, 프로세스는 무시하던지 지정된 함수를 호출하든지 한다.

 그렇지 않다면 기본행동을 취하게 된다.

 

 #.kill 함수

 

 #include <sys/types.h>

 #include <signal.h>

 

 int kill(pid_t pid, int sig);

 

 pid : 프로세스의 PID

 sig : 시그널 번호

 

 #.sig 번호 종류

 * 양의 정수    : 지정한 프로세스 ID에만 시그널을 전송

 * 0    :       함수를 호출하는 프로세스와 같은 그룹에 있는 모든 프로세스에 시그널을 전송

 * -1    : 함수를. 호출하는 프로세스가 전송할 수 있는 권한을 가진 모든 프로세스에 시그널을 전송

 * -1 이외의 음수 :   첫번째 인수 pid 의 절대값 프로세스 그룹에 속하는 모든 프로세스에 시그널을 전송

 

예제

결과

 

 

 

kill은 다른 프로세스에게 시그널을 보낼 수 만 있다. 자신에게 전달된 시그널을 catch해서 처리할 수 없다.

 

 #.자신에게 전달되는 시그널을 처리 할 수 있는 함수.

 

 #include <signal.h>

 

 typedef void (*sighandler_t)(int);

 

 sighandler_t signal(int signum, sighandler_t handler);

 

 signum : 제어할 시그널 번호

 sighandler_t : signum을 받았을 때, 호출할 함수

 

예제

결과

ctrl + c를 누르면 프로세스가 종료되지 않고 시그널 함수가 호출되면서 시그널 함수 안의 소스가 실행이 된다.

 

시그널 특징 : 대기열이 없다. 프로세스는 동시에 단 하나의 시그널만 처리를 할 수 있다. 프로그램을 실행시키고 ctrl+c를 한번 누르면 sig_handler 함수가 호출 된다. 이후 4초를 기다리게 되는데, 그때도 ctrl+c를 여러번 누르면 아무런 반응이 없다. 시그널 대기열이 있다면 4초간격을 두고 한번씩 실행되는데, 한번만 실행이 된다.

예제

결과

 

 

 

 

 

 

 

 

 

 

참고 : 유닉스시스템 프로그래밍(한빛미디어) , joinC