11. 시그널

김동웅·2021년 11월 14일
0

UNIX

목록 보기
12/14

1. 시그널

- 시그널 : 예기치 않은 사건 발생 시 이를 알리는 소프트웨어 인터럽트

ex)
1. SIGFPE : 부동소수점 오류
2. SIGPWR : 정전
3. SIGALARM : 알람시계 울림
4. SIGCHLD : 자식프로세스 종료
5. SIGINT : 키보드로부터 종료 요청 (Ctrl + C)
6. SIGSTP : 키보드로부터 정지 요청 (Ctrl + Z)

시그널 생성

  • 터미널에서 생성된 시그널
  1. CTRL + C -> SIGINT
  2. CTRL + Z -> SIGSTP
  • 하드웨어 예외가 생성하는 시그널
  1. 0으로 나누기 -> SIGFPE
  2. 유효하지 않는 메모리 참조 -> SEGSEGV
  • kill() 시스템 호출
  1. 프로세스(그룹)에 시그널 보내는 시스템 호출
  2. 프로세스의 소유자이거나 슈퍼유저이어야 함
  • 소프트웨어 조건
  1. SIGALRM : 알람 시계 울림
  2. SIGPIPE : 끊어진 파이프
  3. SIGCHLD : 자식 프로세스가 끝났을 때 부모에 전달되는 시그널

주요 시그널


시그널 생성

  • 터미널에서 생성된 시그널
  1. CTRL+C -> SIGINT
  2. CTRL-Z -> SIGSTP
  • 하드웨어 예외가 생성하는 시그널
  1. 0으로 나누기 -> SIGFPE
  2. 유효하지 않는 메모리 참조 -> SIGSEGV
  • kill() 시스템 호출
  1. 프로세스(그룹)에 시그널 보내는 시스템 호출
  2. 프로세스의 소유자이거나 슈퍼유저이어야 함.
  • 소프트웨어 조건
  1. SIGALRM : 알람 시계 울림
  2. SIGPIPE : 끊어진 파이프
  3. SIGCHLD : 자식프로세스가 끝났을때 부모에 전달되는 시그널

- 시그널 처리

  • 기본 처리 동작
  1. 프로세스 종료시킨다(terminate)
  2. 시그널 무시(ignore)
  3. 프로세스 중지(suspend)
  4. 프로세스 계속(resume)

- alarm()

#include <unistd.h>
unsigned int alarm(unsigned int sec)

// sec초 후에 프로세스에 SIGALRM 시그널이 발생되도록 설정한다.

  • alarm(0) : 이전에 설정된 알람 취소

  • 한 프로세스 당 오직 하나의 알람만 설정가능.
    : 이전에 설정된 알람이 있으면 취소되고 남은 시간(초)를 반환
    : 이전에 설정된 알람이 없으면 0 리턴


2. 시그널 처리

시그널에 대한 처리함수 지정

  • signal() 시스템 호출
    : 이 시그널이 발생하면 이렇게 처리해라
#include <signal.h>
signal(int signo, void (*func) )
signo에 대한 처리함수를 func로 지정하고 기존의 처리함수를 리턴
  • 시그널 처리함수 func
  1. SIG_IGN : 시그널 무시
  2. SIG_DFL : 기본처리
  3. 사용자 정의 함수 이름
  • pause()
    시그널을 받을 때까지 해당 프로세스를 잠들게 만든다
  • sigaction() 함수
    : signal()보다 정교하게 시그널 처리기를 등록하기 위한 함수
#include <signal.h>
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
// signum 시그널(SIGKILL과 SIGSTOP 제외)이 수신되었을 때, 프로세스가 취할 액션을 변경하는 데 사용된다. 이 시그널에 대한 새로운 액션은 act가 되며, 기존의 액션은 oldact에 저장된다. 성공하면 0을 실패하면 –1를 반환한다.

struct sigaction {
	void (*sa_handler)(int); // 시그널 처리기
	void (*sa_sigaction)(int, siginfo_t *, void *); 
	sigset_t sa_mask; // 시그널을 처리하는 동안 차단할 시그널 집합
	int sa_flags; 
};

ex) sigint2.c

#include <stdio.h>
#include <signal.h>
struct sigaction newact;
struct sigaction oldact;
void sigint_handler(int signo);

void sigint_handler(int signo)
{ 
	printf("%d번 시그널 처리\n",signo);
    printf("또 누르면 종료됩니다\n");
    sigaction(SIGINT,&oldact,NULL); // 기존 처리 액션으로 변경
}

int main()
{
	newact.sa_handler = sigint_handler; // 시그널 처리기 지정
    sigfillset(&newact.sa_mask); // 모든 시그널을 차단하도록 마스크
    
    // SIGINT의 처리 액션을 새로 지정, oldact에 기존 처리 액션을 저장
    sigaction(SIGINT, &newact, &oldact);
    
    
    while(1)
    {
    	printf("CTRL + C를 눌러보세요 \n");
        sleep(1);
    }
    
 }
    

3. 시그널 보내기

  • kill 명령어
    : 한 프로세스가 다른 프로세스를 제어하기 위해 특정 프로세스에 임의의 시그널을 강제적으로 보낸다.

  • kill() 시스템 호출
    : 특정 프로세스 pid에 원하는 임의의 시그널 signo를 보낸다.
    : 보내는 프로세스의 소유자가 프로세스 pid의 소유자와 같거나 혹은 보내는 프로세스의 소유자가 슈퍼유저이어야 한다.__

#include <sys/types.h>
#include <signal.h>

int kill(int pid, int signo);
// 프로세스 pid에 시그널 signo를 보낸다. 성공하면 0 실패하면 -1 리턴한다.
  • pid > 0 : 프로세스 ID가 pid인 프로세스에 신호
  • pid == 0 : 보내는 프로세스의 프로세스그룹ID와 동일한 그룹ID를 갖고있는 프로세스들에 신호
  • pid < 0 : 프로세스 그룹 ID가 -pid인 프로세스들에 신호

시그널을 이용한 프로세스 제어

  • SIGCONT : 프로세스 재개
  • SIGSTOP : 프로세스 중지
  • SIGKILL : 프로세스 종료
  • SIGTSTP : CTRL+Z에서 발생
  • SIGCHLD : 자식 프로세스 중지 혹은 종료시 부모 프로세스에 전달

0개의 댓글

관련 채용 정보