IPC - SIGNAL

Jongwon·2021년 12월 18일
0

Linux Programming

목록 보기
20/25

IPC(Inter-Process Communication)

프로세스간의 신호를 주고 받거나 정보 공유, Kernel에 의해 지원
IPC의 발전
기존 UNIX: SIGNAL, PIPE, NAMED PIPE
UNIX SYSTEM V: Shared Memory, Message Queue, Semaphore
Posix IPC: System V IPC의 인터페이스 개선

Signal

프로세스간의 신호를 전달, 프로세스간 Signal로 동기화 및 정보 전달 시 이용

시그널 대응

  • 시그널 무시(ignore)
    • SIGKILL, SIGSTOP 제외하고는 모든 시그널 변경하여 무시가능
    • 하드웨어 오류에 의해 발생한 시그널은 주의해야함
  • 시그널 처리(catch)
    • 시그널 발생 시 미리 등록된 handler 실행
    • SIGKILL, SIGSTOP은 등록 불가
  • 기본 처리(default)
    • 대부분은 무시나 프로세스 종료

Signal 생성

  • 한 프로세스가 다른 프로세스에게 kill() 시스템 호출로 통해 전달.
  • 커널이 프로세스에 전달(alarm, 프로세스 종료 시 death of child 시그널, 에러 시그널)
  • 사용자가 인위적으로 생성(Ctrl+C, Ctrl+\ 등 키보드 입력)

시그널 처리

  1. 프로세스 실행 직전 signal 번호와 해당하는 handler 함수 지정.
    • 이때 프로그래머가 지정 안하면 default 핸들러 지정
  2. 프로세스 실행
  3. 타이머가 끝나거나, 스케줄링을 받았을 때 등으로 커널모드에서 유저모드로 돌아갈 때, 받은 signal 확인 후, 해당하는 signal handler 실행 후에 유저모드로 돌아감.

Signal 종류

  • SIGHUP(1) : 터미널 연결이 단절되었을 때
  • SIGINT(2) : Ctrl+C 입력 시 터미널에서 동작하는 프로세스에 인터럽트로 실행 중지
  • SIGQUIT(3) : Ctrl+\ 입력 시 종료 후 코어 덤프 생성
  • SIGILL(4) : 잘못된 명령 사용 시
  • SIGTRAP(5) : 디버거
  • SIGIOT(6) : IOT instruction
  • SIGABRT(6) : abort signal, 후에 SIGIOT로 대체됨
  • SIGEMT(7) : EMT 명령 실행 시
  • SIGFPE(8) : floating point 예외처리(산술연산 예외)
  • SIGKILL(9) : kill 시그널, 무시불가
  • SIGBUS(10) : bus 에러
  • SIGSEGV(11) : Segmentation fault
  • SIGSYS(12) : bad argument
  • SIGPIPE(13) : read하는 pipe 파일이 없는 write pipe 파일이 시그널을 보냄
  • SIGALRM(14) : alarm clock
  • SIGTERM(15) : 작업 종료 시그널, kill을 받은 프로세스
  • SIGUSR1(16) : user defined signal
  • SIGUSR2(17) : user defined signal
  • SIGCLD(18) : child 상태가 변경될 때
  • SIGPWR(19) : power-fail restart
  • SIGWINCH(20) : window size 변경 시
  • SIGURG(21) : 소켓에서 긴급한 상태
  • SIGPOLL(22) : pollable 이벤트 발생 시
  • SIGIO SIGPOLL : 소켓 I/O가 가능할때
  • SIGSTOP(23) : Ctrl+S로 stop 프로세스 멈출 시
  • SIGTSTP(24) : terminal에서 stop 요청 올 시
  • SIGCONT(25) : Ctrl+Q로 프로세스 continue 시
  • SIGTTIN(26) : background tty가 read 시도 발생 시
  • SIGTTOU(27) : background tty가 write 시도 발생 시
  • SIGVTALRM(28) : virtual timer 만료 시
  • SIGPROF(29) : profiling timer 만료 시
  • SIGXCPU(30) : CPU 한계 넘었을 시
  • SIGXFSZ(31) : 파일 사이즈 한계 넘었을 시
  • SIGWAITING(32) : process lwps가 막혔을 시
  • SIGLWP(33) : thread library에서 발생한 시그널
  • SIGFREEZE(34) : CPR에서 발생한 시그널
  • SIGTHAW(35) : CPR에서 발생한 시그널
  • SIGCANCEL(36) : thread cancel
  • SIGLOST(37) : 자원 실종



signalhandler함수는 다음과 같다.

void *signalhandler_t(int signo) {
	등록할 handler코드
}

<signal.h> 헤더

  • sighandler_t signal(int signo, sighandler_t handler) 시그널 handler 등록
    에러 있다면 -1반환하고 errno변수에 EINTR 저장
sighandler_t handler
- SIG_IGN : 시그널 무시
- SIG_DFL : 기본 동작
- SIG_ERR : 시그널 등록 에러
  • int kill(pid_t pid, int signo)
    signo 시그널 전송, 0은 성공, -1은 에러
signo == 0이면 실제로 시그널을 전송하지는 않고, 프로세스의 존재여부만 파악, 존재안하면 -1
pid > 0이면 pid 프로세스에게 전달
pid == 0이면 pid의 그룹ID가 같은 모든 프로세스에 전달
pid < 0이면 그룹ID가 |pid|인 모든 프로세스에 전달
  • int raise(int signo)
    자신에게 스스로 시그널 보냄, 0은 성공, -1은 에러
  • int sigemptyset(sigset_t *set) set을 0으로 초기화
  • int sigfillset(sigset_t *set) set을 1로 세팅
  • int sigaddset(sigset_t *set, int signo) signo로 지정된 시그널을 set에 추가
  • int sigdelset(sigset_t *set, int signo) set에서 signo로 지정된 signal 제거
  • int sigismember(const sigset_t *set, int signo) signo 시그널이 set의 멤버인지 검사
커널에서 signal을 받으면 pending signal bitmap에 저장.
각 비트 자리에 해당하는 signo가 온다면, 1로 바꾸고, 유저모드로 돌아갈 때, bitmap의 모든 1 확인
  • int sigprocmask(int how, const sigset_t set, sigset_t oset)
    mask bitmap 설정하라고 OS에 알림
int how
- SIG_BLOCK: 기존에 설정된 mask에서 set에 설정된 시그널들을 mask에 추가
- SIG_UNBLOCK: 기존에 설정된 mask에서 set에 설정된 시그널들을 mask에서 제거
- SIG_SETMASK: set인자로 시그널 마스크 대체

sigset_t *oset
oset이 NULL이 아니면 이전의 블록된 시그널 set값이 저장됨.
set == NULL이면 oset에 기존 마스크값 얻음
pending bitmap vs mask bitmap
pending map에는 받은 signal들을 중복을 제거하여 저장. 시그널이 실행되면 0으로 돌아감.
mask bitmap은 signal 처리하지 않을 함수들을 1로 설정. 0으로 돌아갈 때 시그널 실행.
  • int sigpending(sigset_t *set)
    pending중인 signal들(mask되어 대기중인 signal)을 set에 넣어줌

  • int sigsuspend(const sigset_t *set)
    mask를 set으로 설정하고, pause하라. errno에 에러면 EINTR, 포인터에러면 EFAULT, race contition 제거 가능

<unistd.h> 헤더

  • unsigned int alarm(unsigned int second)
    seconds 후에 SIGALRM 시그널 전송, 0 혹은 인자로 0줄땐 이전에 남아있던 알람 잔여시간 반환
한 프로세스엔 하나의 알람만 존재. 이미 알람이 설정된 상태에서 호출 시 이전 알람이 리턴되고, 새로운 알람으로 설정
  • void pause(void)
    signal올 때까지 정지
profile
Backend Engineer

0개의 댓글