(리눅스 시스템 프로그래밍) OS Signal + C예제코드
by 줌코딩
Signal이란?
- 의미를 전달하는 방법으로 시그널과 메세지는 조금의 차이를 지닌다.
- 시그널은 하나의 의미만을 지니고 있으며 간단하고 빠른 전달을 위해 사용된다.
- 하지만 복잡한 내용 전달에는 사용되지 않는다.
Signal in OS
인간과 OS 사이에는 응용프로그램이 존재한다. 물론 메세지로 데이터 통신을 할 수도 있겠지만 굳이 이렇게 복잡한 통신이 필요하지 않다면 이런 통신은 불필요하다고 볼 수 있다. 때문에 OS는 여러 Signal을 지원하여 단순한 통신을 가능하게 하였다.
예제1. SIGINT Handler
키보드 입력으로 발생시킬 수 있는 시그널은 여러 종류가 있다.
- Ctrl+C : SIGINT (프로세스를 종료시킨다.)
- Ctrl+Z : SIGSTP (프로세스를 중단시킨다.)
- Ctrl+\ : SIGQUIT (core dump를 남기고 프로세스를 종료시킨다.)
이 중에 SIGINT라는 신호를 handling하는 함수를 한번 실행 시켜보자.
signal1.c
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
void handler(int sig){
//SIGINT라는 신호가 오면 유저한테 물어본다.
if (sig == SIGINT) {
printf("Do you want to quit?") ;
if (getchar() == 'y')
exit(0) ;
}
}
int main(){
signal(SIGINT, handler) ;
while(1) ;
}
결과는 아래와 같이 Ctrl+C가 실행되면 핸들러가 일하게 된다.
jeongjinhyeog-ui-MacBook-Pro:IPC jeongjinhyeog$ ./signal1
^CDo you want to quit?y
예제2. SIGTERM 활용 프로그램 죽이기
유저가 언제 프로그램을 죽일지 모르기 때문에 시그널을 보내 이벤트로 처리하는 것이 좋다.
SIGTERM은 프로그램을 종료하기 전에 프로그램을 종료하는 처리를 수행한다.
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
void handler(int sig){
printf("Do you want to quit?") ;
if (getchar() == 'y')
exit(0) ;
}
int main(){
int d ;
//TERM은 SIGINT와 다르다.
//Exit을 코드로 짜는 것보다 유저가 언제든 끌 수 있게 시그널로 하는 것이 좋다.
//두개의 프로그램 사이에 시그널으로 통신할 수 있다.
//엄청난 정보는 아니더라도 간단하게 서로에게 신호를 줄 수 있다. (시그널 자체로는 데이터를 주고 받을 수는 없다.)
signal(SIGTERM, handler) ;
scanf("%d", &d) ;
}
이 프로그램을 실행하면 signal을 기다리게 된다.
jeongjinhyeog-ui-MacBook-Pro:IPC jeongjinhyeog$ ./signal2
ps를 이용해서 해당 프로세스의 id를 찾고 죽여보자.
jeongjinhyeog-ui-MacBook-Pro:Programmers jeongjinhyeog$ ps
PID TTY TIME CMD
70415 ttys000 0:00.11 -bash
70427 ttys001 0:00.51 -bash
36680 ttys002 0:00.19 -bash
39987 ttys002 0:00.00 ./signal2
40021 ttys003 0:00.03 -bash
jeongjinhyeog-ui-MacBook-Pro:Programmers jeongjinhyeog$ kill 39987
그 후 해당 프로세스를 실행중인 terminal을 확인해보면 핸들러가 실행된 것을 볼 수 있다.
jeongjinhyeog-ui-MacBook-Pro:IPC jeongjinhyeog$ ./signal2
Do you want to quit?
예제 3. SIGALRM 활용 알람 보내기
SIGALRM은 알람을 보내주는데 활용되는 시그널이다.
- t라는 itimerval 변수를 생성하고 시간 주기를 설정해주고
- setitimer를 사용하면 핸들러로 원하는 시간을 보내줄 수 있다.
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
void
handler(int sig)
{
printf("Ring\n") ;
}
int main(){
struct itimerval t ;
//알람 타이머
signal(SIGALRM, handler) ;
//시간의 양을 정한다
t.it_value.tv_sec = 1 ;
t.it_value.tv_usec = 100000 ; // 1.1 sec
//interval을 주면 시간 간격마다 링하게 된다.
t.it_interval = t.it_value ;
//시간을 설정하는 함수로 일정 시간이 되면 시그널을 보내게 할 수 있다.
setitimer(ITIMER_REAL, &t, 0x0) ;
while (1) ;
}
실행 시 일정한 간격을 두고 계속해서 Ring이 울리는 것을 볼 수 있다.
jeongjinhyeog-ui-MacBook-Pro:IPC jeongjinhyeog$ ./signal3
Ring
Ring
Ring
Ring
Ring
Ring
느낀점
일단 많은 양의 복잡한 내용을 보내는 데는 사용할 수 없겠지만 빠른 단순한 통신에는 매우 용이할 것 같다!
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
Subscribe via RSS