Signal Handler
Signal Handler
시그널이 발생했을 때 어떻게 그 시그널을 처리할 것인가
시그널 핸들러
시그널 수신 시 호출할 함수(시그널핸들러)를 등록한다.
signal(SINALARM, tcp_timer);
alarm을 10초 설정해놨다고 치면, SIGALARM 이 발생하는 10초동안 다른일 하다가 끝나면 tcp_timer로 점프
signal(SIGINT, SIG_IGN)
SIGINT가 발생하면 ctrl-c로 프로세스를 종료시킬 수 있다. 이를 종료되지 않게 막는게 (sig_ignore)SIG_ING
->SIGINT가 발생하면 SIG_IGN이라는 이벤트가 발생하도록 한다.
사용자가 정의한 함수로 점프하거나, 시그널을 무시하거나, 일반적으론 종료가 되게 한다.
(함수-이벤트 나열은 옛날 표기법임)
시그널 집합
- <bits/sigset.h> 에 있다.
- sigset_t를 사용하면 여러개의 시그널을 한 번에 표시할 수 있다.
주요함수
#include <signal.h>
int sigemptyset(sigset_t *set); //시그널 집합 set을 비운다
int sigfillset(sigset_t *set); //set에 모든 시그널을 포함시킨다
int sigaddset(sigset_t *set, int signum); //set에 signum시그널을 추가한다.
int sigdelset(sigset_t *set, int signum); //set에서 signum시그널을 삭제한다.
int sigismember(const sigset_t *set, int signum); //set에 signum시그널이 포함되어있는지 확인한다.
일단 시그널을 채워놔야 이벤트가 발생하면 시그널핸들러(함수)로 점프한다.
- 시그널 집합에 SIGINT만 남기는 코드
sigset_t signals;
sigemptyset(&signals); //set에서 모든 시그널을 비운다음에
sigaddset(&signals, SIGINT); //SIGINT만 추가시킴
- 시그널 집합에 SIGINT 시그널만 빠져있는 집합을 만드는 코드
sigset_t signals;
sigfillset(&signals); //모든 시그널을 set에 저장한 후
sigdelset(&signals, SIGINT); //SIGINT만 삭제
- 시그널 집합에 SIGINT 시그널이 존재하는지 확인하는 함수
sigset_t signals;
sigemptyset(&signals); //모든 시그널 비우기
sigaddset(&signals, SIGINT); //SIGINT 넣기
if(sigismember(&signals, SIGINT)) //당연히 true의 결과
printf("this is true\n");
if(sigismember(&signals, SIGPIPE)) //현재 set에는 SIGINT뿐. 당연한 false의 결과
printf("this is false\n");
sigaction()
- 시그널 발생시 호출할 함수(시그널 핸들러) 등록에 사용
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
signum : 처리할 시그널 (SIGKILL과 SIGSTOP제외)
act : signum 시그널 도착시 sigaction 구조체 관련 처리
sigaction 구조체는 <bits/sigaction.h>에 있다.
많이 사용하는 sa_handler (시그널 핸들러), sa_mask (시그널 핸들러 실행중에 블록시킬 시그널)
int sa_flags(환경설정)
sigaction,restore 은 배제하고 생각
sa_flags
SA_RESTART : 이전에 수행하던 시스템콜을 계속 수행하게 해준다.
SA_NOCLDWAIT : child 프로세스가 죽을 때 까지 기다리지 말아라 - 라는 함수
SA_NODEFER : 누적되도록함
SA_ONESHOT or SA_RESETHAND : 아마 사용할 일은 없을것이다