Linux/UNIX2012. 11. 10. 00:51

컴퓨터에서 시그널이란 프로세스가 예측하지 못한 이벤트로부터 발생한 인터럽트를 말하는 것이다. 

인터럽트의 종류는 대략 다음과 같다.

1. 불법적인 연산 (=0으로 어떤 수를 나누기)

2. 컴퓨터 파워의 고장

3. 알람

4. 자식 프로세스의 종료

5. 유저의 입력에 의한 종료와 중단 (Ctrl + C, Ctrl + Z)


signal() 함수는 위에서 명시한 시그널들의 처리를 어떻게 할 것인가를 설정하는 함수이다.

즉, 어떤 시그널이 발생하면 직접 처리를 할것인지 기존에 사용하던 방법을 따를것인지 혹은 무시를 할것인지를 signal()함수를 통해서 설정할 수 있다는 것이다.


헤더

 #include<signal.h>

형태

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

인수 

 int signum              시그널 번호

 void (*handler)(int) 시그널을 처리할 핸들러

반환 

 void *()(int);이전에 설정된 시그널 핸들러


예제


#include<stdio.h> // timelimit.c

#include<signal.h>


int delay;

void childHandler( );


int main(int argc, char *argv[]){

int pid;


sscanf(argv[1], "%d", &delay); //delay = strrol(argv[1], 0, 0);

signal(SIGCHLD, childHandler);

pid = fork();        //ceate child

if(pid == 0){ //child

execvp(argv[2], &argv[2]);

perror("Limit");

}else{ //parent

sleep(delay);

printf("Child %d exceeded limit and is being killed\n", pid);

kill(pid, SIGINT);

}

}


void childHandler( ){ /* Executed if the child dies before the parent */

int childPid, childStatus;

childPid = wait(&childStatus);

printf("Child %d terminated within %d seconds\n", childPid, delay);

exit(0);

}


결과





1. 예제에 대한 간략한 설명을 하자면, 메인함수가 시작되면서 프로세스 실행시 사용자가 입력시켜 주었던 argv[1]인자(실행 화면에서 입력한 5)는 sscanf로 전역변수 delay에 할당된다. 


2. 이어서 예제의 중간부에 나온 fork()를 통해서 자식프로세스가 생성되는 것을 볼 수있다. 자식 프로세스는 사용자가 입력해 주었던 두번째 값을 실행시킨다. 이 때 부모 프로세스는 초기에 입력시켜 주었던 5 동안 sleep명령어를 진행하고 있다. 


3. 자식 프로세스의 작업이 끝나면 자식 종료에 대한 시그널이 발생하며 코드의 11번째 라인에있는 시그널 처리함수에 걸려서 핸들러함수로 이동하여 시그널에 대한 처리를 진행하게 된다. 


4. 만약 자식 프로세스가 수행하는 명령어가 5초 이상의 시간을 필요로 하는 작업이라면, 부모가 그동안 진행하고 있던 5초 간의 sleep 함수가 종료되면서 부모가 먼저 자식 프로세스를 kill하게 된다.


이 과정 중 집중해서 봐야할 부분은 3번이다.


signal(SIGCHLD, childHandler);

함수의 첫 번째 인자인 SIGCHLD는 자식 프로세스가 종료될 때 부모에게 전달되는 시그널이다. 즉, 자식 종료 이벤트를 캐치할 것이라고 명시한것으로 보면 된다. 두 번째 인자는 자식이 종료되는 시그널이 발생한다면 사용자가 작성한 childHandler함수로 가서 시그널을 처리할 것임을 알려주는 것이다.

이 글에서는 설명하지 않았지만 #include<signal.h>에는 31가지 이벤트에 대한 시그널 집합 변수가 있는데 참조하고 싶은 분은 아래의 링크로 가서 나오는 글의 테이블을 보시면된다. 

Posted by twinjh