반응형


- 본 내용은 Linux (Ubuntu 14.04 lts)를 기반으로 제작되었습니다. -







이전 게시물에서 kill 함수를 통한 SIGINT에 대해 알아보았다.


이번에는 signal 함수를 이용하여 SIGINT를 어떻게 이용하고 구성할지 생각해본다.



우선 시그널에 대한 개념은 다음과 같다.


시그널은 small message이고, 이벤트를 알려주기 위해 쓰는 메시지이다.


커널에서 예외처리 및 인터럽트를 위해 시그널을 보내거나, 다른 프로세스에서도 보내기도 한다.


시그널은 정수 id로 구성되어 있다.


signal에 대한 다양한 정보는 다음 게시물에서 확인 가능하다. http://www.crocus.co.kr/245


예를들어 SIGINT(ctrl + c)를 보내면 SIGINT에 해당하는 시그널이 켜지는 것이다.


시그널이 발동하는 몇가지 조건은 다음과 같다.


1. 0으로 나눌 때

2. 자식 프로세스가 꺼질 때

3. KILL로 프로세스를 끌 때

4. 한 프로세스에서 시그널을 요청할 때

등등


만약 시그널이 보내졌는데 도착지에서 못받았을 때를 pending된다고 한다.


시그널은 타입마다 최대 한개만 pending할 수 있다.


즉, 시그널은 큐로 구성되어 있지 않고, SIGINT를 5번 보내도 1번만 보냈다고 인식한다.



이전 게시물에서 확인한 kill 함수도 함수명은 kill이지만 단지 signal을 send하는 함수일 뿐이다.



다음 코드는 signal에서 SIGINT를 이용한 코드이다.


signal의 원형은 다음과 같다.


handler_t *signal(int signum, handler_t *handler);


즉, 시그널 타입에 맞는 핸들러를 설치하는 것이고, 성공시 이전 핸들러를 반환 실패시 SIG_ERR을 반환한다.


signal(SIGINT, (void *)sig_handler);은 SIGINT를 설치한 것이고


SIGINT(ctrl + c)를 받으면 sig_handler함수에 의해 동작하게 한다는 의미이다.


즉, 아래에 있는 printf에 해당하는 내용을 출력할 것이다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <signal.h> 
#include <unistd.h> 
#include <stdio.h>
 
void sig_handler(int signo); 
 
int main()
{
    int i = 0;
    signal(SIGINT, (void *)sig_handler);
 
    while(1)
    {
        printf("%d\n", i);
        i++;
        sleep(1);
    }
    return 1;
}
 
 
void sig_handler(int signo)
{
    printf("\nYou can't ctrl + c me\n");
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus









결과 화면을 보면, while에 의해 계속 1씩 값이 올라가며 출력된다.


하지만 그 사이에 ctrl + c를 누르면 SIGINT 시그널이 발동하는데 이미 SIGINT는 sig_handler로 설치해 둔 상태이기에,


종료되지 않고 printf의 내용이 출력된다.







반응형