Search
Duplicate
🗣️

minitalk (3) 시그널 구조

간단소개
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
C
42cursus
minitalk
Scrap
태그
9 more properties
minitalk
시그널(Signal)
비동기적으로 프로세스에 무언가 발생했음을 알리는 표준 신호

시그널 종류

Ctrl + C 입력 시 SIGTERM 신호가 전달된다.
과제에서 허용된 시그널은 SIGUSR1, SIGUSR2 이다.
Search
No
이름
기본 액션
비고
구분
2
terminate process
프로그램 인터럽트
종료 신호
3
create core image
프로그램 종료
종료 신호
4
create core image
적합하지 않은 명령어
오류 신호
5
create core image
트레이스 트랩
오류 신호
6
create core image
이전 SIGIOT 프로그램에 대해
오류 신호
7
create core image
에뮬레이트 명령어 실행
오류 신호
8
create core image
부동소수점 예외
오류 신호
9
terminate process
프로그램 종료
종료 신호
10
create core image
버스 에러
오류 신호
11
create core image
세그먼테이션 위반
오류 신호
12
create core image
존재하지 않은 시스템 호출
오류 신호
13
terminate process
reader가 없는 파이프에 쓰기
동작 오류 신호
14
terminate process
실시간 타이머 만료
경보 신호
15
terminate process
소프트웨어 종료 신호
종료 신호
16
discard signal
소켓 긴급 신호 상태
비동기 I/O 신호
17
stop process
중지 (시그널 처리, 무시, 차단 불가능)
작업 제어 신호
18
stop process
키보드로 인한 중지
작업 제어 신호
19
discard signal
정지 후 프로세스 유지
작업 제어 신호
20
discard signal
자식 프로세스 상태 변경
작업 제어 신호
21
stop process
백그라운드 읽기 터미널 제어 시도
작업 제어 신호
22
stop process
백그라운드 쓰기 터미널 제어 시도
작업 제어 신호
23
discard signal
I/O 디스크립터 가능 (fcntl(2) 참조)
비동기 I/O 신호
24
terminate process
cpu 시간 제한 초과 (setrlimit(2) 참조)
동작 오류 신호
25
terminate process
파일 크기 제한 초과 (setrlimit(2) 참조)
동작 오류 신호
26
terminate process
가상 시간 알람 (settimer(2) 참조)
경보 신호
27
terminate process
프로파일링 타미어 알람 (settimer(2) 참조)
경보 신호
28
discard signal
윈도우 크기 변경
기타
29
discard signal
키보드에서 상태 요청
기타
30
terminate process
사용자 정의 신호1
기타
31
terminate process
사용자 정의 신호2
기타
32
terminate process
스레드 인터럽트
33
terminate process
실시간 라이브러리 인터럽트

시그널 동작 방식

1.
signal() 또는 sigaction() 함수로 시그널 핸들러를 등록한다.
2.
유저 모드에서 인터럽트가 발생하면 커널 모드로 진입하여 등록된 시그널 핸들러를 수행한다.
3.
모든 처리가 완료되면 다시 정상 프로그램 흐름으로 돌아간다.

시그널 객체

sig_atomic_t

비동기 신호가 발생하는 경우에도 원자 엔티티로 접근할 수 있는 정수 유형
typedef int __sig_atomic_t; typedef __sig_atomic_t sig_atomic_t;
C
복사
C 언어는 sig_atomic_t 자료형에 대해 원자형(atomic) 읽기, 쓰기를 보장한다.
flag++ 같이 다수의 명령을 필요하는 동작은 안전성을 보장하지 않으므로 단순 플래그 및 객체 참조 목적으로 사용해야 한다.

sigaction

시그널 핸들러에 대한 정보를 담고 있는 자료 구조체
struct sigaction { union __sigaction_u __sigaction_u; /* signal handler */ sigset_t sa_mask; /* signal mask to apply */ int sa_flags; /* see signal options below */ }; union __sigaction_u { void (*__sa_handler)(int); void (*__sa_sigaction)(int, siginfo_t *, void *); }; #define sa_handler __sigaction_u.__sa_handler #define sa_sigaction __sigaction_u.__sa_sigaction int sigaction(int sig, const struct sigaction *restrict act, struct sigaction *restrict oact);
C
복사
__sigaction_u 공용체
sa_handler : signal 함수를 위한 간단한 함수 포인터
sa_sigaction : sigaction 함수를 위한 상세한 함수 포인터
sa_mask 시그널 집합
핸들러 실행 중 블록될 시그널 집합을 설정한다.
sa_mask를 지정하지 않으면 핸들러가 실행되는 도중 핸들러가 다시 실행된다. (데이터 꼬임!)
sa_mask를 지정하면 핸들러가 실행되는 도중 블럭처리가 되어 무시된다.
무시된 시그널은 대기열에 등록된다.
단, 동일한 시그널이 대기열에 등록중이라면 그 시그널은 정말로 무시된다. (시그널 누락!)
sa_flags 플래그
SA_ONSTACK (0x00000001)
sigaltstack()에 설치된 대체 스택을 사용해 이 시그널에 대한 핸들러를 실행한다.
SA_ONESHOT SA_RESETHAND (0x00000002)
시그널의 기본 처리 방법은 SIG_DFL로 재설정되고 시그널이 처리되는 동안 시그널을 블록하지 않는다.
SA_NOMASK SA_NODEFER (0x00000010)
시그널이 처리되는 동안 유닉스 커널에서 해당 시그널을 자동으로 블록하지 않는다.
SA_RESTART (0x00000004)
시그널 핸들러에 의해 중지된 함수를 재시작한다.
SA_SIGINFO (0x00000008)
시그널에 대한 더 많은 정보를 제공하는 추가적인 인자로 시그널 핸들러를 실행한다. - siginfo_t 구조체와 context 정보가 같이 전달된다.
SA_NOCLDWAIT (0x00010000)
SIGCHLD인 경우에, 자식들이 제거될 때 좀비 프로세스로 만들지 않는다.
SA_NOCLDSTOP (0x00020000)
SIGCHLD라면, 자식 프로세스가 SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU등을 받아서 중단되었을 때 부모 프로세스에 SIGCHLD 시그널을 전달하지 않는다.

siginfo_t

시그널에 대한 정보를 담고 있는 자료 구조
void ft_handler(int sig, siginfo_t *info, void *ucontext) { ... } siginfo_t { int si_signo; /* 시그널 번호*/ int si_errno; /* 시그널 관련 오류번호 */ int si_code; /* 시그널 발생 원인을 정의하는 코드 */ int si_trapno; /* Trap number that caused hardware-generated signal (unused on most architectures) */ pid_t si_pid; /* Sending process ID */ uid_t si_uid; /* Real user ID of sending process */ int si_status; /* Exit value or signal */ clock_t si_utime; /* User time consumed */ clock_t si_stime; /* System time consumed */ sigval_t si_value; /* Signal value */ int si_int; /* POSIX.1b signal */ void *si_ptr; /* POSIX.1b signal */ int si_overrun; /* Timer overrun count; POSIX.1b timers */ int si_timerid; /* Timer ID; POSIX.1b timers */ void *si_addr; /* Memory location which caused fault */ long si_band; /* Band event (was int in glibc 2.3.2 and earlier) */ int si_fd; /* File descriptor */ short si_addr_lsb; /* Least significant bit of address (since Linux 2.6.32) */ void *si_lower; /* Lower bound when address violation occurred (since Linux 3.19) */ void *si_upper; /* Upper bound when address violation occurred (since Linux 3.19) */ int si_pkey; /* Protection key on PTE that caused fault (since Linux 4.6) */ void *si_call_addr; /* Address of system call instruction (since Linux 3.5) */ int si_syscall; /* Number of attempted system call (since Linux 3.5) */ unsigned int si_arch; /* Architecture of attempted system call (since Linux 3.5) */ }
C
복사

프로세스 구조

요약
sighand의 각 시그널 번호에 핸들러 등을 포함한 sigaction 구조체가 등록된다.
특정 프로세스의 시그널이 보류되는 경우 pending에 저장된다.
스레드 그룹의 시그널이 보류되는 경우 signal→shared_pending에 저장된다.
struct task_struct : 프로세스와 관련된 모든 정보를 담고 있는 디스크립터
Type
Name
설명
struct signal_struct *
signal
시그널 디스크립터
struct sighand_struct *
sighand
핸들러 디스크립터
sigset_t
blocked
블록된 시그널 마스크
sigset_t
real_blocked
임시로 블록된 시그널 마스크 (rt_sigtimedwait() 시스템콜 사용)
struct sigpending
pending
private 보류 신호를 저장하는 자료 구조
unsigned long
sas_ss_sp
대체 시그널 핸들러 스택 주소
size_t
sas_ss_size
대체 시그널 핸들러 스택 크기
int (*) (void *)
notifier
프로세스의 일부 시그널을 차단하기 위한 장치 드라이버 용 함수 포인터
void *
notifier_data
notifier 함수에서 사용하는 데이터 (테이블의 이전 필드)
sigset_t *
notifier_mask
notifier 함수를 사용하여 장치 드라이버에 의해 차단된 시그널의 비트 마스크
struct sigpending 관련
위치
이름
설명
관련 함수
시그널 디스크립터
shared_pending
shared 보류 신호 큐는 스레드 그룹의 보류 신호를 저장
kill, rt_sigqueueinfo
프로세스 디스크립터
pending
private 보류 신호 큐는 특정 프로세스의 보류 신호를 저장
tkill, tgkill

참고