Signal Conceps

  • 프로그램 수행 중 여러가지 이벤트가 발생
    • floating point error
    • 파워가 꺼지기 직전 경고
    • 알람기능
    • child process가 종료됐을 경우 parent로 알림
    • Ctrl + C : 정해진 명령
    • Ctrl + Z : 중단
  • 이러한 이벤트들을 signal이라고 부름
  • 비동기적인 이벤트를 프로세스에 알려줌 - ex) Ctrl + C를 누를 경우 알림을 줘야하는데 언제 주는지는 정확히 모름
  • Signal 발생시 프로세스에게 전달이 되고 다양한 액션을 취함
    1. 무시
    2. signal을 catch : 적합한 함수를 호출해줌 -> signal handler
    3. 함수를 명시적으로 등록하지 않았더라도 default된 액션을 취함
      1. 무시
      2. 프로세스 종료
      3. 프로세스 종료 후 core dump라는 파일(상태값 - 레지스터 값, 메모리의 값)을 만듦 -> 프로그램을 디버그할 때 사용가능
      4. 프로세스를 중지(일시정지)시킴
      5. 만약 정지되어 있다면 다시 수행을 재개

    Linux Signals

     

    • signal.h라는 헤더파일에 int형으로 저장되어 있으나 Name형식으로 정의되어 있음
      • SIGALRM : 알람을 울려줌 -> 14번, default는 term(terminated - 프로세스 종료)
      • SIGCHLD : child process가 종료 되었을 때 부모 프로세스가 받는 것 -> default는 무시
      • SIGCONT : 프로세스가 중단되어 있을 때 이 시그널을 받으면 다시 재개 -> default는 cont(재개)
      • SIGKILL : 이 시그널을 받으면 반드시 죽음
      • SIGPWR : 시스템의 파워가 곧 꺼질 것이라는 알림
      • SIGSEGV : 잘못된 메모리의 접근 시 알림 -> default는 core(특정 상태를 파일에 dump) - 이 파일로 분석 가능
      • SIGSTOP : Ctrl + Z와 같은 기능 -> 프로세스를 잠시 정지
      • SIGTERM : process termination -> SIGKILL과는 다르게 signal handler로 처리가능
      • signal(2)/signal(7)에 많은 정보가 있음

    Dispatching Signals: kill(2) and raise(3)

    • signal을 특정 프로세스에 보낸다는 의미
    • kill(2) and raise(3)

    • kill(2)
      1. pid라는 프로세스에게 지정한 signo을 보내는 것 - ex) pid = 100이라는 프로세스에 SIGTERM을 보냄
      2. pid > 0 : 해당하는 pid에 시그널을 보냄
      3. pid = 0 : 0으로 설정하면 signal을 보내는 프로세스와 같은 그룹ID를 가지는 모든 프로세스에게 지정한 signal을 보냄 -> broadcast, multi-cast
      4. pid<-1,pid = -1
        1. pid 가 -1 이면, 1번 프로세스를 제외한 모든 프로세스에서 시그널을 보냄
        2. pid 가 -1 보다 작으면, -pid 프로세스가 포함된 모든 그룹의 프로세스에게 시그널을 보냄
      • raise(3)
        1. kill(getpid(),signo)와 같은 역할 -> 자기 자신에게 시그널을 보냄

      signal delivery and handler execution

       

      • 프로그램이 수행중에 언제 외부의 signal이 도착할지 알 수 없음
      • 프로그램이 실행되는 중간에 signal이 도착하면 프로그램은 잠시 수행을 중단하고 signal handler라는 함수에 감
      • signal에 해당하는 일을 처리 후 return
      • signal을 받았던 장소로 돌아와서 명령 수행
      • 어느 시점에 오는지 정확히 모르므로 비동기적인 처리를 해야함

      setting up a Signal Handler: signal(2)

      • signal handler를 등록하는 방법
      • signal(2)

      • signum - 지정한 시그널 번호/handler - handler 등록 -> type은 지정한 함수에 대한 fucntion pointer
      • sighandler_t : return값 -> 예전에 이미 등록된 함수 handler의 function pointer를 반환
      • SIG_IGN : 지정한 시그널을 무시
      • SIG_DFL : default action
      • 위 둘 다 아니라면 명시적으로 signal handler를 등록
      • 요즘에는 signal(2)이라는 함수보다 sigaction(2)이라는 함수를 많이 사용
      • 예제

      1. SIGINT : signum/ ouch : 함수 -> 지정

      2. 1초 마다 반복

      3. 만약 SIGINT가 Ctrl + C라면 프로그램 실행 중 Ctrl + C를 하면 ouch 함수를 수행


      sigaction(2)

      • signal함수와 같은 역할이나 좀 더 정밀한 작업에 사용됨 -> thread나 real-time signal 등

      • signum에 해당하는 sigaction이라는 structer에 저장

      1. 첫 번째가 handler부분 - signal이 발생했을 때 실행
      2. sa_mask : signal이 동작하는 동안에 이곳에 저장된 signal들이 오면 막아줌
      • 현재 리눅스에서는 sigaction으로 구현되어 있으므로 간단한 경우를 제외하고는 이 시스템 콜을 사용할 것

      signal sets

      • 여러 시그널을 한 세트로 지정

      • sigemptyset : set에 대한 pointer를 주면 비워버림
      • sigfillset : 전체 집합으로 설정 - 전부 1로
      • sigaddset : 지정된 signum을 추가
      • sigdelset : 지정된 signum을 제거
      • sigismember : signum이 포함되어 있는지 알려줌
      • 예제

      1. sigaction을 사용
      2. sigemptyset으로 비움
      3. flag를 0또는 NULL으로 지정
      4. ouch라는 handler등록
      5. SIGINT가 왔을 때 sa에 지정된 handler를 수행
      6. sa_mask를 비웠기 때문에 아무런 signal도 막지 않고 받아들인다는 뜻
      7. sigaction의 세 번째 파라미터는 입력된 handler가 등록이 되어있다 하면 예전의 handler를 리턴
      8. while로 반복하며 Ctrl + C를 누르면 지정한 핸들러가 호출됨

      Signal Mask

      • 시그널이 오는 것을 막을 수 있음

      • how에 대한 action을 취함/set
        1. SIG_BLOCK : set에 지정한 시그널들을 이미 블록된 signal들에 합산하여 막아줌
        2. SIG_UNBLOCK : set에 지정된 시그널들은 signal이 전달 될 수 있도록 설정
        3. SIG_SETMASK : set에 지정된 시그널들을 block시켜줌
      • sigpending : 시그널이 block되어 대기하는 상태 -> 이러한 시그널들이 무엇이 있는지 파악하여 set에 반환
      • 예제

      1. block_set을 비움
      2. SIGINT를 추가 -> 비운 후 추가 했으므로 SIGINT만 설정
      3. sigprocmask : 현재 blocking되어있는 signal set에 block_set을 추가/이전에 지정된 signal set들을 prev_set에 리턴
      4. 아래 함수가 수행되는동안 Ctrl+C를 눌러도 block되어 (pending)대기 -> 여러번 누르더라도 1개만 저장 됨
      5. sigprocmask : 이전 blocking set들을 다시 되돌려 놓음 -> SIGINT가 없을 때의 상태
      6. 이 후 바로 이전에 눌렸던 pending된 signal이 바로 전달되어 default action인 term을 실행
      7. for루프에 가기전에 프로세스가 끝나버림

       


      Timers, and Sleeping

      • 일정 시간이 경과하면 알림

      • second만큼 지나면 SIGALRM이 프로세스에 도착
      • 만약 seconds=0이면 setting해놓은 알람을 canceled
      • 알람은 프로세스에서 딱 1개만 설정
      • POSIX interval timers가 Unix에 추가됨 -> 여러개의 timer setting가능
      • 예제

      1. handler등록
      2. sigaction : SIGALRM에 handler 등록
      3. alarm(5) : 5초로 등록
      4. 반복문이 진행되다가 5초가 지나면 지정된 함수를 실행
      5. waiting = 0이므로 반복문 종료

      sleep(3), nanosleep(2)

      • 지정된 시간동안 프로그램 수행을 중단시킴

      • seconds동안 정지
      • msec, nsec로 정밀하게 조정가능 : nanosleep -> timespec을 받음

      1. tv_sec은 second, tv_nsec은 nanosecond
      • 두 번째 파라미터 rem : sleep중 인터럽트를 받아 종료 되었을 때, 남은 초를 반환 

       

       

       

       

       

       

       

      + Recent posts