(본 강의 노트는 한빛 아카데미의 <유닉스 시스템 프로그래밍> 책을 기반으로 하고 있습니다)
Ch07. 시그널
학습목표
- 시그널의 기본 개념을 이해한다.
- 시그널을 보내는 방법을 이해한다.
- 시그널을 받아서 처리하는 기본적인 방법을 이해한다.
- 시그널 집합의 개념과 사용방법을 이해한다
- sigaction 함수를 사용해 시그널을 처리하는 방법을 이해한다.
- 알람 시그널의 처리방법을 이해한다.
- 시그널 관련 기타 함수들의 사용방법을 이해한다.
목차
1. 시그널의 개념
2. 시그널의 종류
3. 시그널 보내기
4. 시그널 핸들러 함수
5. 시그널 집합
6. sigaction 함수의 활용
7. 알람시그널과 인터벌 타이머
8. 기타 시그널 관련 함수
01. 시그널의 개념
시그널이란?
소프트웨어 인터럽트 프로세스에 뭔가 발생했음을 알리는 간단한 메시지를 비동기적으로 보내는 것
발생사유
1. 0으로 나누기처럼 프로그램에서 예외적인 상황이 일어나는 경우
2. kill 함수처럼 시그널을 보낼 수 있는 함수를 사용해서 다른 프로세스에 시그널을 보내는 경우
3. 사용자가 Ctrl+C(강제중단)와 같이 인터럽트 키를 입력한 경우
시그널 처리 방법
1. 각 시그널에 지정된 기본 동작 수행(대부분의 기본 동작을 프로세스 종료)
2. 시그널 무시
3. 시그널 처리를 위한 함수(시그널 핸들러)를 지정해놓고 시그널을 받으면 해당 함수 호출
4. 시그널이 발생하지 않도록 블록처리
02. 시그널의 종류
1. $kill -l : 시그널의 종류를 보여줌
2. signal reference table
03. 시그널 보내기
Kill 명령
- 프로세스에 시그널을 보내는 명령
- $kill -9 3255 : 3255번 프로세스에 9번 시그널(SIGKILL) 보내기 -> 프로세스 강제 종료
시그널 보내기: Kill()
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
- pid > 0 : pid로 지정한 프로세스에 시그널 발송 (해당 함수의 주요 목적)
- pid가 -1이 아닌 음수 : 프로세스 그룹 아이디가 pid의 절대 값인 프로세스 그룹에 속한 모든 프로세스에 시그널 발송
- pid == 0 : 자기와 같은 프로세스 그룹안의 모든 프로세스에게 시그널을 발송
- pid == -1 : 시그널을 보내는 프로세스가 effective user id를 가지면 해당 id와 같은 모든 프로세스에 시그널 발송
시그널 보내기: raise()
- 함수를 호출한 프로세스에 시그널 발송
시그널 보내기: abort()
- 함수를 호출한 프로세스에 SIGABRT시그널 발송
- SIGABRT시그널은 프로세스를 비정상적으로 종료시키고 코어덤프 생성
04. 시그널 핸들러 함수
시그널 핸들러
- 시그널을 받았을 때 이를 처리하기 위해 지정된 함수
- 프로세스를 종료하기 전에 처리할 것이 있거나, 특정 시그널에 대해 종료하고 싶지 않을 경우 지정
시그널 핸들러 지정 : signal()
#include <signal.h>
void (*signal(int sig, void (*disp)(int)))(int);
- disp : sig로 지정한 시그널을 받았을 때 처리할 방법
- 시그널 함수는 시그널이 들어올 때마다 시그널 핸들러를 호출하려면 매번 시그널 핸들러를 재지정해야 함
시그널 핸들러 지정 : sigset()
#include <signal.h>
void (*sigset(int sig, void (*disp)(int)))(int);
- disp : sig로 지정한 시그널을 받았을 때 처리할 방법
05. 시그널 집합
시그널 집합의 개념
- 시그널을 개별적으로 처리하지 않고 복수의 시그널을 처리하기 위해 도입한 개념
- POSIX에서 도입
시그널 집합의 처리를 위한 구조체
typedef struct {
unsigned int __val[4]; //in Linux
} sigset_t;
- 시그널을 비트 마스크로 표현. 각 비트가 특정 시그널과 1:1로 연결
- 비트 값이 1이면 해당 시그널이 설정(on)된 것이고, 0이면 시그널 설정 안된 것(off)임
시그널 집합 비우기 : sigemptyset()
- 시그널 집합에서 모든 시그널을 0으로 설정
시그널 집합에 모든 시그널 설정 : sigfillset()
- 시그널 집합에서 모든 시그널을 1으로 설정
시그널 집합에 시그널 설정 추가 : sigaddset()
- signo로 지정한 시그널을 시그널 집합에 추가
시그널 집합에서 시그널 설정 삭제 : sigdelset()
- signo로 지정한 시그널을 시그널 집합에서 삭제
시그널 집합에 설정된 시그널 확인: sigismemner()
- signo로 지정한 시그널이 시그널 집합에 포함되어 있는지 확인
06. sigaction 함수의 활용
Sigaction 함수
- 시그널이나 sigset함수처럼 시그널을 받았을 때 이를 처리하는 함수 지정
- 시그널 함수보다 다양하게 시그널 제어 가능
Sigaction 구조체
- sa_flags에 지정할 수 있는 값
sigaction 함수
#include <signal.h>
int sigaction(int sig, const struct sigaction *restrict act, struct sigaction *restrict oact);
- 첫번째 인자로 SIGKILL과 SIGSTOP을 제외한 어떤 시그널도 올 수 있음
- sa_flags에 SA_SIGIFO 플래그를 지정하면 시그널 발생원인을 알 수 있다.
시그널 발생 원인 코드
시그널 발생 원인 출력 : psiginfo
#include <signal.h>
void psignifo(siginfo_t *pinfo, char *s);
- pinfo : 시그널 발생원인 정보를 저장한 구조체
- s : 출력할 문자열
07. 알람 시그널과 인터벌 타이머
알람 시그널
알람 시그널
- 일정한 시간이 지난 후에 자동으로 시그널이 발생하도록 하는 시그널
알람 시그널 생성 : alarm
#include <unistd.h>
unsigned int alarm(unsigned int sec);
- sec : 알람이 발생시킬 때까지 남은 시간(초 단위)
- 일정 시간이 지나면 SIGALRM 시그널 발생
- 프로세스별로 알람시계가 하나 밖에 없으므로 알람은 하나만 설정 가능
인터벌 타이머
타이머의 종류
타이머 정보 검색 : gettimer()
#include <sys/time.h>
int getitimer(int which, struct itimerval *value);
타이머 설정 : settimer()
#include <sys/time.h>
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
- which : 타이머 종류
- value : 타이머 정보 구조체 포인터
08. 기타 시그널 관련 함수
시그널 블록킹과 해제
#include <signal.h>
int sighold(int sig);
int sigrelse(int sig);
- 인자로 받은 시그널을 시그널 마스크에 추가하거나 해제
시그널 집합 블록과 해제 : sigprocmask()
#include <signal.h>
int sigprocmask(int how, const sigset_t *restrict set,sigset_t *restrict oset);
시그널 대기 : sigpause()
#include <signal.h>
int sigpause(int sig);
- sig : 시그널이 올 때까지 대기할 시그널
시그널 기다리기 : sigsuspend()
#include <signal.h>
int sigsuspend(const sigset_t *set);
- set : 기다리려는 시그널을 지정한 시그널 집합
시그널 무시처리 : sigignore()
#include <signal.h>
int sigignore(int sig);
- sig : 무시할 시그널 번호
- 인자로 지정한 시그널의 처리방법은 SIG_IGN으로 설정
'Computer Science > 유닉스프로그래밍' 카테고리의 다른 글
[유닉스 시스템 프로그래밍] Ch09. 파이프 (0) | 2020.11.23 |
---|---|
[유닉스 시스템 프로그래밍] Ch08. 메모리 매핑 (0) | 2020.11.16 |
[유닉스 시스템 프로그래밍] Ch06. 프로세스 생성과 실행 (0) | 2020.10.19 |
[유닉스 시스템 프로그래밍] Ch05. 프로세스 정보 (0) | 2020.10.19 |
[유닉스 시스템 프로그래밍] Ch04. 시스템 정보 (0) | 2020.10.19 |