시그널(signal) : 어떤 이벤트(인터럽트, 타이머종료)가 발생 했을 때 운영체제가 프로그램에 이를 알리는 기법을 뜻합니다

 

현재 실행되고 있는 프로그램에 시그널이 전달되었을시 4가지 상황이 발생합니다

 

1. (운영체제의 의해) 시그널이 무시된다. 프로세서는 시그널이 도착한 것을 알지 못한다

2. 운영체제는 프로그램을 강제로 종료한다

3. 프로그램 실행이 인터럽트 되면 이후에 프로그램이 지정한 시그널 처리 루틴이 실행

4. 시그널이 블로킹된다 프로그램이 시그널을 허용 할 때 까지 아무런영향을 미치지 못한다 해당프로세서에서는 어떠시그널이 블록되었는지 마스크를 가지고 있다

 

종류

이벤트

기본동작

SIGALARM

알람 타이머의 만료

프로그램 종료

SIGCHLD

자식 프로세서가 종료됨

시그널 무시

SIGINT

인터럽트 문자(Ctrl C)입력됨

프로그램 종료

SIGIO

소켓에 대해 I/O 가 준비됨

시그널 무시

SIGPIPE

종료된 소켓에 쓰기를 시도할때

프로그램 종료

 

시그널은 상당히 복잡해서 전채를 다 아는 것은 어렵습니다 몇가지 시그널이 소켓에 자주 등장하여서 아주 중요합니다!!

sigaction
구조체를 이용한  sigaction 함수 그리고 원형 

 

#include <signal.h> 
 
int sigaction(int signum, const struct sigaction * act, struct sigaction * oldact); 
성공시 0실패   -1 리턴 
 
struct
 sigaction 
    { 
           void (*sa_handler)(int)  //
시그널 처리할 함수 
           sigset_t sa_mask; //
시그널처리함수가 실행되는 동안 블로킹될 시그널을 설정 
           int sa_flags;            //
옵션 설정 
    }


참고>>
시그널은 큐(queue)에 대기 되지 않고 계류 되거나 또는 버려지거나 둘중하나입니다 만약 시그널이 처리되는 도중에 똑 같은 종류의 시그널이 두 개 이상 도착한다면 시그널 핸들러는 기존에 진행하던 핸들러를 마치고 한번더 실행하게 됩니다

 
SIGINT를 활용하여 Ctrl -c 입력시 종료하는 프로그램

/* sigaction.c */

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

int my_signal();  //새로운 시그널 처리함수 선언
int count = 0;     //Ctrl-C 입력 횟수 카운터

int main()
{
  int i = 0;

  struct sigaction act;         //sigaction 구조체 변수
  act.sa_handler = my_signal;   //시그널 처리함수 지정
  sigemptyset(&act.sa_mask);    //sm_mask의 모든 비트를 0으로 설정
  act.sa_flags = 0;

  if(sigaction(SIGINT, &act, 0== SIG_ERR)
  {
    printf("sigaction() error \n");
    exit(1);
  }

  while(count < 3)
  {
    sleep(1);   //1초간 대기
    printf("%d \n", i++);
  }
  return 0;
}

int my_signal()
{
  printf("\nCtrl-C pressed \n");
  count++;

  return 0;
}


결과>>


Ctrl - C을 3번 눌렀을 경우 종료되는 것을 확인 할 수 있습니다.


SIGALARM을 활용하여 정해진 시간에 종료하는 프로그램
/* sigtimer.c */

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

void timer(int sig);

int main()
{
  int i = 0;

  struct sigaction act;         //sigaction 구조체 변수
  act.sa_handler = timer;   //시그널 처리함수 지정
  sigemptyset(&act.sa_mask);    //sm_mask의 모든 비트를 0으로 설정
  act.sa_flags = 0;

  if(sigaction(SIGALRM, &act,0)  == SIG_ERR)
  {
    puts("sigaction() error \n");
    exit(1);
  }

  alarm(5);
  
  while(1)
  {
    puts("대기중");
    sleep(1);   
  }
  return 0;
}

void timer(int sig)
{
  printf("\n시간이 되었습니다 종료합니다\n");
  exit(0);
}



결과>>


5초후(대기중 1초) 프로그램이 종료되는 것을 확인 할 수 있습니다
Posted by mantwo