시그널이란
- 소프트웨어 인터럽트
- 프로세스에게 특정 이벤트가 발생했음을 알리는 수단
- 다양한 시그널이 있고, 시그널 종류별로 번호가 할당되어 있다
대표적인 시그널
- SIGCHLD:Child stopped or terminated
- SIGILL:lllegal Instruction
- SIGINT:Interrupt from keyboard(Ctrl+C)
- SIGKILL:KILL signal(처리 불가능)
- SIGEGV:Invaild memory reference
시그널
- 시그널마다 기본 동작이 정해져 있고, 처리가 가능한 것들이 있다
- 무시도 처리의 일부이다
- $ man 7 signal
특정 프로세스 (그룹)에게 시그널 보내기
int kill(pid_t pid, int sig);
- Parameter
- pid:시그널을 보낼 대상
= 1: PID
- == 0: 프로세스 그룹 모두에게 전송
- == -1: 권한이 허락하는 한 모든 프로세스
- < =1: 프로세스 그룹 아이디가 (-pid)인 프로세스 그룹 전체
- sig:전송할 시그널 번호
- Return
자기 자신에게 시그널 보내기
int rasie(int sig);
시그널 처리
sighandler_t signal(int signum, sighandler_t handler);
- Parameter
- signum:처리할 시그널 번호
- handler:시그널 핸들러(시그널이 동작하는 방법)
- 사용자가 정의한 시그널 동장 함수 주소
- SIG_DFL(기본)
- SIG_IGN(무시)
- Return
- 성공시 이전 시그널 핸들러 언제든 이전 시그널 설정으로 돌아갈 수 있도록
- 실패시 SIG_ERR
심화) 시그널 집합 관리:시그널 마스킹
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 포함 여부 검사
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
- Parameter
- signum:처리할 시그널 번호(SIGKILL, SIGSTOP 적용 불가)
- act:지정한 시그널에 대해 취해야할 정보
- oldact:이전에 지정되어 있었던 시그널 처리 정보
- Return
struct sigactiom{
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void*);
sigset_t sa_mask;
int sa_flags;
}
sa_handler:시그널 핸들러
- signum에 해당하는 시그널이 들어왔을 때 취해야 할 행동
- SIG_DFL:기본 동작
- SIG_IGN:무시(SIGSTOP, SIGKILL 제외)
- 함수 포인터(사용자가 지정한 함수 주소)
- sa_flags가 SA_SIGINFO로 지정되어 있다면 sa_sigaction 실행
시그널 번호 뿐 아니라 시그널로 보낸 프로세스의 PID 등 다양한 정보를 알 수 있음 보통 sa_handler, sa_sigaction 둘 중 하나만 사용토록 권장
- sa_mask:시그널 마스크
- 시그널 핸들러가 실행되는 동안 봉쇄(처리 연기)할 시그널들 실행 중인 핸들러가 종료되면 그 때 처리