컴퓨터에서 시그널이란 프로세스가 예측하지 못한 이벤트로부터 발생한 인터럽트를 말하는 것이다.
인터럽트의 종류는 대략 다음과 같다.
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번이다.
'Linux/UNIX' 카테고리의 다른 글
리눅스/유닉스의 시스템 구조(커널과 쉘) (0) | 2012.12.16 |
---|---|
Command-Line Argument. agrv[argc] (0) | 2012.11.23 |
프로세스 종료 exit() _exit() atexit() (1) | 2012.11.21 |
strtol() - 정수문자열을 진수를 선택하여 정수로 반환 (0) | 2012.11.07 |
파일 허가권(File Permissions)과 UID(user id) (0) | 2012.11.07 |