Skip to content

Latest commit

ย 

History

History
614 lines (458 loc) ยท 16.9 KB

File metadata and controls

614 lines (458 loc) ยท 16.9 KB

Chapter7. ์‹œ๊ทธ๋„

  • signal

    • software interrupt
    • kernel => process / process => process
    • ์ž๋ฃŒ ์ „์†ก๋ณด๋‹ค๋Š” ๋น„์ •์ƒ์ ์ธ ์ƒํ™ฉ์„ ์•Œ๋ฆด ๋•Œ ์‚ฌ์šฉ
    • ์‹คํ–‰ ํ”„๋กœ์„ธ์Šค ์ค‘๋‹จ์‹œํ‚ค๋Š”๊ฒŒ ์›๋ž˜ ๋ชฉ์ 
  • ์˜ˆ) program ์ˆ˜ํ–‰ ์ค‘ CTRL + C (interrupt key) ๋ˆ„๋ฅด๋ฉด, kernel์ด ๋ฌธ์ž๋ฅผ ๊ฐ์ง€ ํ›„ ํ•ด๋‹น session์— ์žˆ๋Š” ๋ชจ๋“  process์—๊ฒŒ SIGINT ๋ผ๋Š” signal์„ ๋ณด๋‚ธ๋‹ค. ๋ชจ๋“  process๋Š” ์ข…๋ฃŒ๋˜์ง€๋งŒ shell process๋Š” ๋ฌด์‹œ

  • signal ์ข…๋ฅ˜

    1. SIGHUP: ์—ฐ๊ฒฐ๋œ terminal์ด hangup ํ–ˆ์„ ๋•Œ(terminate)
    2. SIGINT: interrupt key(^C)๋ฅผ ์ž…๋ ฅํ–ˆ์„ ๋•Œ(terminate)
    3. SIGQUIT: quit key(^\)๋ฅผ ์ž…๋ ฅํ–ˆ์„ ๋•Œ(terminate+core)
    4. SIGILL: illegal instruction์„ ์ˆ˜ํ–‰ํ–ˆ์„ ๋•Œ(terminate+core)
    5. SIGTRAP: implementation defined hardware fault (terminate+core)
    6. SIGABRT: abort ์‹œ์Šคํ…œ์ฝœ์„ ๋ถˆ๋ €์„ ๋•Œ(terminate+core)
    7. SIGBUS: implementation defined hardware fault (terminate+core)
    8. SIGFPE: arithmetic exception, /0, floating-point overflow (terminate+core)
    9. SIGKILL: process๋ฅผ kill ํ•˜๊ธฐ ์œ„ํ•œ signal, catch ํ˜น์€ ignore ๋  ์ˆ˜ ์—†๋Š” signal(terminate)
    10. SIGUSR1: user defined signal 1 (terminate)
    11. SIGSEGV: invalid memory reference (terminate+core)
    12. SIGUSR2: user defined signal 2 (terminate)
    13. SIGPIPE: reader๊ฐ€ terminate ๋œ pipe์— writeํ•˜๋Š” ๊ฒฝ์šฐ ๋ฐœ์ƒ(terminate)
    14. SIGALRM: alarm ์‹œ์Šคํ…œ์ฝœ ํ›„ timer๊ฐ€ expire๋œ ๊ฒฝ์šฐ(terminate)
    15. SIGTERM: kill ์‹œ์Šคํ…œ์ฝœ์ด ๋ณด๋‚ด๋Š” software termination signal (terminate)
    16. SIGCHLD: child๊ฐ€ stop or exit๋˜์—ˆ์„ ๋•Œ parent์—๊ฒŒ ์ „๋‹ฌ๋˜๋Š” ์‹ ํ˜ธ(ignore)
    17. SIGCONT: continue a stopped process (continue/ignore)
    18. SIGSTOP: sendable stop signal, cannot be caught or ignored (stop process)
    19. SIGTSTP: stop key(^Z)๋ฅผ์ž…๋ ฅํ•˜์˜€์„๋•Œ(stop process)
    20. SIGTTIN: background process๊ฐ€ control tty๋กœ๋ถ€ํ„ฐ readํ•  ๊ฒฝ์šฐ(stop process)
    21. SIGTTOU: background process๊ฐ€ control tty๋กœ writeํ•  ๊ฒฝ์šฐ(stop process)
    22. SIGURG: urgent condition on IO, socket์˜ OOB data (ignore)
    23. SIGXCPU: exceeded CPU time limit (terminate+core/ignore)
    24. SIGXFSZ: exceeded file size limit (terminate+core/ignore)
    25. SIGVTALRM: virtual time alarm, setitimer, (terminate)
    26. SIGPROF: profiling time alarm, setitimer, (terminate)
    27. SIGWINCH: terminal window size changed, (ignore)
    28. SIGIO: ์–ด๋–ค fd ์—์„œ asynchronous I/O event๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๊ฒฝ์šฐ(terminate/ignore)
    29. SIGPWR: system power fail (terminate/ignore)
    30. SIGSYS: bad argument to system call (terminate+core)
    
    ์ถœ์ฒ˜: http://jangpd007.tistory.com/90 [์ฐธ ๋†€๋ผ์šด ์„ธ์ƒ]
    
  • signal์˜ ๊ธฐ๋ณธ์ฒ˜๋ฆฌ

    • ์ข…๋ฃŒ(signal์— ์˜ํ•œ ์ •์ƒ ์ข…๋ฃŒ)
    • ์ฝ”์–ด๋คํ”„ ํ›„ ์ข…๋ฃŒ(signal์— ์˜ํ•œ ๋น„์ •์ƒ ์ข…๋ฃŒ) : core file(์ข…๋ฃŒ์ง์ „์˜ memory ์ƒํƒœ) ์ƒ์„ฑ ํ›„ ์ข…๋ฃŒ
    • ์ค‘์ง€
    • ๋ฌด์‹œ
    1. SIG_DFL (SIG_PF)0
    2. SIG_ERR (SIG_PF)-1
    3. SIG_IGN (SIG_PF)1
    4. SIG_HOLD (SIG_PF)2
    
    ์ถœ์ฒ˜: http://jangpd007.tistory.com/90 [์ฐธ ๋†€๋ผ์šด ์„ธ์ƒ]
    
  • Child process์˜ ์ข…๋ฃŒ ์ƒํƒœ ํ™•์ธ

    #include <sys/wait.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    int main(int argc, char **argv) {
      pid_t pid;
      int status, exit_status;
    
      if((pid = fork()) < 0) {
        perror("fork failed");
        exit(1);
      }
    
      if(pid == 0) {
        sleep(4);
        exit(5);
      }
    
      if(pid=wait(&status) == -1) {
        perror("wait failed");
        exit(2);
      }
    
      if(WIFEXITED(status)) {
        exit_status = WEXITSTATUS(status);
        printf("Exit status from %d was %d\n", pid, exit_status);
      }
    
      exit(0);
    }
    • ์‹œ๊ทธ๋„์„ ๋ฐ›๊ณ  ์ข…๋ฃŒํ•œ ๊ฒฝ์šฐ, WTERMSIG ์‹œ๊ทธ๋„ ๋ฒˆํ˜ธ๋ฅผ ๋ฐ˜ํ™˜ํ•จ
    if(WIFSIGNALED(status)) {
      printf("%d\n", WTERMSIG(status));
    }
  • signal ๋ณด๋‚ด๊ธฐ

    • pid : signal์„ ๋ฐ›๊ฒŒ๋  process ์ง€์ •
    • sig : ๋ณด๋‚ผ signal ์ง€์ •
    #include <sys/types.h>
    #include <signal.h>
    
    int kill(pid_t pid, int sig);
    • ์‹œ๊ทธ๋„์„ ๋ฐ›์„ process ๋˜๋Š” process group ์ง€์ • ๊ฐ€๋Šฅ
      • pid > 0 : ํ•ด๋‹น id์˜ process์—๊ฒŒ signal ์ „๋‹ฌ
      • pid = 0 : sender์™€ ๊ฐ™์€ process group์— ์†ํ•˜๋Š” ๋ชจ๋“  process์—๊ฒŒ signal ์ „๋‹ฌ. sender ์ž์‹ ๋„ ํฌํ•จ
      • pid = -1: uid๊ฐ€ sender์˜ euid์™€ ๊ฐ™์€ ๋ชจ๋“  process์—๊ฒŒ signal ์ „๋‹ฌ. sender ์ž์‹ ๋„ ํฌํ•จ
      • pid < 0 & pid != -1 : process์˜ group id๊ฐ€ pid์˜ ์ ˆ๋Œ€๊ฐ’๊ณผ ๊ฐ™์€ ๋ชจ๋“  process์—๊ฒŒ signal ์ „๋‹ฌ. -7800 : 7800 group์— ๋™์‹œ์— ์‹œ๊ทธ๋„ ๋ณด๋‚ด๊ฒ ๋‹ค
    • ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž์˜ process์—๊ฒŒ signal์„ ๋ณด๋‚ด๋ฉด -1 return. ๋‚˜์˜ process์—๊ฒŒ๋งŒ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๊ณ , kernel๋งŒ ์•„๋ฌด process์— ๋‹ค ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Œ
    • raise : raise ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ process์—๊ฒŒ ์ง€์ •ํ•œ sig๋ฅผ ๋ณด๋‚ธ๋‹ค
    #include <signal.h>
    
    int raise(int sig);
  • Signal handling

    • ๊ธฐ๋ณธ๋™์ž‘ ์ˆ˜ํ–‰. default action. ๊ฐ ์‹œ๊ทธ๋„์€ ๊ธฐ๋ณธ ๋™์ž‘์ด ์ง€์ •๋˜์–ด ์žˆ์Œ
    • ์ง€์ •๋œ ํ•จ์ˆ˜ ์ˆ˜ํ–‰. ์ •์˜๋œ action. ํŠน์ • ํ•จ์ˆ˜ ๋งŒ๋“ค์–ด์„œ ์‹คํ–‰
    • ์‹œ๊ทธ๋„ ๋ฌด์‹œ
  • ์ฑ…์—๋Š” signal, sigset ์žˆ๋Š”๋ฐ ์ˆ˜์—… ๋•Œ ์•ˆ ํ•จ. ๋ฐ”๋กœ sigaction ๊ตฌ์กฐ์ฒด ์‚ฌ์šฉํ•ด์„œ ์‹œ๊ทธ๋„ ์ฒ˜๋ฆฌํ•จ

  • sigaction

    • sigaction ์ง€์ • : signal ์ˆ˜์‹  ์‹œ ์›ํ•˜๋Š” ํ–‰๋™์„ ์ทจํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค

    • SIGSTOP(process์˜ ์ผ์‹œ์ค‘๋‹จ), SIGKILL(process์˜ ์ข…๋ฃŒ)์˜ ๊ฒฝ์šฐ๋Š” ๋ณ„๋„์˜ action์„ ์ทจํ•  ์ˆ˜ ์—†๋‹ค

    • ์ง€์ • ๋ฐฉ๋ฒ•

      #include <signal.h>
      
      int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);
      
      struct sigaction{
        void (*sa_handler)(int);
        sigset_t sa_mask;
        int sa_flags;
        void(*sa_sigaction)(int, siginfo_t *, void *)
      }
    • void(*sa_handler)(int);

      • signo๋ฅผ ์ˆ˜์‹ ํ•˜๋ฉด ์ทจํ•  ํ–‰๋™ ์ง€์ •
      • SIG_DFL. default ํ–‰๋™, ์ฆ‰ ์ข…๋ฃŒ
      • SIG_IGN. ๋ฌด์‹œ
      • ์ •์˜๋œ ํ•จ์ˆ˜. signal์„ ๋ฐ›์œผ๋ฉด ํ•จ์ˆ˜๋กœ ์ œ์–ด ์ด๋™, ํ•จ์ˆ˜ ์‹คํ–‰ ํ›„ signal์„ ๋ฐ›๊ธฐ ์ง์ „์˜ ์ฒ˜๋ฆฌ ๋ฌธ์žฅ์œผ๋กœ return
    • sigset_t sa_mask;

      • ์—ฌ๊ธฐ ์ •์˜๋œ signal๋“ค์€, sa_handler์— ์˜ํ•ด ์ง€์ •๋œ ํ•จ์ˆ˜๊ฐ€ ์ˆ˜ํ–‰๋˜๋Š” ๋™์•ˆ blocking ๋œ๋‹ค.
      • ๋‹น์žฅ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๊ณ  ํ˜„์žฌ ์ฒ˜๋ฆฌ ์ค‘์ธ ๊ฒƒ ๋๋‚ด๊ณ  ์ฒ˜๋ฆฌํ•˜๊ฒ ๋‹ค. ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€ signal๋“ค ๋จผ์ € ์ฒ˜๋ฆฌ
    • int sa_flags

      • SA_RESETHAND : handler๋กœ๋ถ€ํ„ฐ ๋ณต๊ท€ ์‹œ signal action์„ SIG_DFL๋กœ ์žฌ์„ค์ •
      • SA_SIGINFO : sa_handler ๋Œ€์‹  sa_sigaction ์‚ฌ์šฉ
  • sigaction ์‚ฌ์šฉ

    • Ctrl + c ์ž…๋ ฅ ๋ฐ›์œผ๋ฉด ์ •์˜ํ•œ ํ•จ์ˆ˜ ์‹คํ–‰
    #include <signal.h>
    
    int main(int argc, char **argv) {
      static struct sigaction act;
      void catchint(int);
    
      act.sa_handler = catchint;
      sigaction(SIGINT, &act, NULL);
    
      printf("sleep call1\n");
      sleep(1);
      printf("sleep call2\n");
      sleep(1);
      printf("exiting\n");
      exit(0);
    }
    
    void catchint(int signo) {
      printf("CATCHINT : %d\n", signo);
      psignal(signo, "[Received Signal]");
    }
  • Ctrl + c ์ž…๋ ฅ ๋ฐ›์œผ๋ฉด ๋ฌด์‹œ

  act.sa_handler = SIG_IGN;
  sigaction(SIGINT, &act, NULL);
  • Ctrl + c ์ž…๋ ฅ ๋ฐ›์œผ๋ฉด ์ข…๋ฃŒ
  act.sa_handler = SIG_DFL;
  sigaction(SIGINT, &act, NULL);
  • ์—ฌ๋Ÿฌ๊ฐœ์˜ ์‹œ๊ทธ๋„ ๋ฌด์‹œํ•˜๋Š” ๊ฒฝ์šฐ
    • SIGINT: interrupt key(^C)๋ฅผ ์ž…๋ ฅํ–ˆ์„ ๋•Œ(terminate)
    • SIGQUIT: quit key(^)๋ฅผ ์ž…๋ ฅํ–ˆ์„ ๋•Œ(terminate+core)
  act.sa_handler = SIG_IGN;
  sigaction(SIGINT, &act, NULL);
  sigaction(SIGQUIT, &act, NULL);
  • ํ•œ ํ”„๋กœ์„ธ์Šค์—์„œ ๋ฌด์‹œ๋˜๋Š” signal์€ exec()ํ›„์—๋„ ๊ณ„์† ๋ฌด์‹œ๋œ๋‹ค. exec์œผ๋กœ ์‹คํ–‰ํ•˜๋ฉด process๊ฐ€ ๋™์ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— signal์„ ๊ณ„์† ๋ฌด์‹œํ•˜๊ฒŒ ๋œ๋‹ค

  • Signal ์ง‘ํ•ฉ ์ง€์ •

    • sigemptyset => sigaddset : ์ „๋ถ€ 0์œผ๋กœ ์„ค์ •ํ•œ ํ›„ blockํ•  ์‹œ๊ทธ๋„ ์„ค์ •

    • sifgillset => sigdelset : ์ „๋ถ€ ๋‹ค 1๋กœ ์„ค์ •ํ•œ ํ›„ blockํ•˜์ง€ ์•Š์„ ์‹œ๊ทธ๋„ ์„ค์ •

    • ์‚ฌ์šฉ๋ฐฉ๋ฒ•

      #include <signal.h>
      
      int sigemptyset(sigset_t *set);
      int sigfillset(sigset_t *set);
      
      int sigaddset(sigset_t *set, int signo);
      int sigdelset(sigset_t *set, int signo);
      
      //0์œผ๋กœ ์„ค์ •๋๋Š”์ง€ 1๋กœ ๋๋Š”์ง€ ํ™•์ธ
      int sigismember(sigset_t *set, int signo);
      sigset_t mask1, mask2;
      
      sigemptyset(&mask1);
      sigaddset(&mask1, SIGINT);
      sigaddset(&mask1, SIGQUIT);
      
      sigfillset(&mask2);
      sigdelset(&mask2, SIGCHLD);
      
      if(sigismember(&mask1, SIGINT))
        printf("SIGINT is setting.\n");
  • ์˜ˆ์ œ

    • ์‹œ๊ทธ๋„ ๋ณด๋‚ด๊ณ  ์ง€์ •๋œ ํ•จ์ˆ˜๋กœ ์ฒ˜๋ฆฌ

      • blockํ•  ์‹œ๊ทธ๋„ ์„ค์ •์„ ์•„๋ฌด๊ฒƒ๋„ ํ•ด์ฃผ์ง€ ์•Š์•˜๊ณ , SIGINT ์‹œ๊ทธ๋„์ด ์˜ค๋ฉด ์ง€์ •๋œ ํ•จ์ˆ˜ ๋ง๊ณ  ๊ธฐ์กด์˜ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๊ฒŒ ์„ค์ •ํ–ˆ์Œ
      #include <stdio.h>
      #include <sys/types.h>
      #include <sys/stat.h>
      #include <sys/wait.h>
      #include <fcntl.h>
      #include <unistd.h>
      #include <dirent.h>
      #include <string.h>
      #include <time.h>
      #include <ftw.h>
      #include <stdlib.h>
      #include <signal.h>
      
      #define BUFSIZE 512
      
      void catchsig(int signo) {
        //์ „๋‹ฌ๋ฐ›์€ ์‹œ๊ทธ๋„์ด ๋ฌด์—‡์ธ์ง€ ์•Œ๋ ค์ฃผ๋Š” ํ•จ์ˆ˜
        psignal(signo, "[Received Signal]");
      }
      
      void do_child() {
        int i;
        static struct sigaction act;
      
        sigemptyset(&act.sa_mask);
        //    sigaddset(&act.sa_mask, SIGINT);
        //    sigaddset(&act.sa_mask, SIGUSR1);
        //    sigaddset(&act.sa_mask, SIGUSR2);
      
        act.sa_handler = catchsig;
      
        //sigaction(SIGINT, &act, NULL);
        sigaction(SIGUSR1, &act, NULL);
        sigaction(SIGUSR2, &act, NULL);
      
        for(i=0;i<5;i++) {
          printf("child is running ... \n");
          sleep(1);
        }
      }
      
      int main(int argc, char **argv) {
        int status;
        pid_t pid;
      
        pid = fork();
      
        if(pid == 0) {
          do_child();
        } else {
          sleep(2);
          kill(pid, SIGINT);
          sleep(1);
          kill(pid, SIGUSR1);
          sleep(1);
          kill(pid, SIGUSR2);
        }
      
        wait(&status);
      
        if(WIFEXITED(status)) {
          printf("Exit status from %d was %d\n", pid, WEXITSTATUS(status));
        } else {
          printf("Exit status from %d was %d\n", pid, WTERMSIG(status));
        }
      
        exit(0);
      }
    • ์‹œ๊ทธ๋„ ๋ณด๋‚ด๊ณ  ์ง€์ •๋œ ํ•จ์ˆ˜๋กœ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ ์ง€์ •๋œ ์‹œ๊ทธ๋„์€ blockํ•˜๊ธฐ

      • blockํ•  ์‹œ๊ทธ๋„๋กœ SIGINT, SIGUSR1, SIGUSR2๋ฅผ ์„ค์ •์„ ํ•ด๋‘์—ˆ์Œ. ๊ทธ๋Ÿฌ๋ฉด ์ผ๋‹จ ์‹œ๊ทธ๋„ ์ฒ˜๋ฆฌ๋Š” ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ๋‹ค๊ฐ€ ์ž์‹ ํ”„๋กœ์„ธ์Šค ์ข…๋ฃŒ ํ›„ block๋œ ์ฒ˜๋ฆฌ๋ฅผ ํ•จ
    • SIGINT ์‹œ๊ทธ๋„์ด ์˜ค๋ฉด ์ง€์ •๋œ ํ•จ์ˆ˜ ๋ง๊ณ  ๊ธฐ์กด์˜ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๊ฒŒ ์„ค์ •ํ–ˆ์Œ

      #include <stdio.h>
      #include <sys/types.h>
      #include <sys/stat.h>
      #include <sys/wait.h>
      #include <fcntl.h>
      #include <unistd.h>
      #include <dirent.h>
      #include <string.h>
      #include <time.h>
      #include <ftw.h>
      #include <stdlib.h>
      #include <signal.h>
      
      #define BUFSIZE 512
      
      void catchsig(int signo) {
        psignal(signo, "[Received Signal]");
      }
      
      void do_child() {
        int i;
        static struct sigaction act;
      
        sigemptyset(&act.sa_mask);
        sigaddset(&act.sa_mask, SIGINT);
        sigaddset(&act.sa_mask, SIGUSR1);
        sigaddset(&act.sa_mask, SIGUSR2);
      
        act.sa_handler = catchsig;
      
        sigaction(SIGINT, &act, NULL);
        sigaction(SIGUSR1, &act, NULL);
        sigaction(SIGUSR2, &act, NULL);
      
        for(i=0;i<5;i++) {
          printf("child is running ... \n");
          sleep(1);
        }
      }
      
      int main(int argc, char **argv) {
        int status;
        pid_t pid;
      
        pid = fork();
      
        if(pid == 0) {
          do_child();
        } else {
          sleep(2);
          kill(pid, SIGINT);
          sleep(1);
          kill(pid, SIGUSR1);
          sleep(1);
          kill(pid, SIGUSR2);
        }
      
        wait(&status);
      
        if(WIFEXITED(status)) {
          printf("Exit status from %d was %d\n", pid, WEXITSTATUS(status));
        } else {
          printf("Exit status from %d was %d\n", pid, WTERMSIG(status));
        }
      
        exit(0);
      }
  • Signal ์ง‘ํ•ฉ ์ง€์ • ์ค‘ sa_sigaction()์— ์˜ํ•œ signal handling

    int main(void) {
        static struct sigaction act;
        act.sa_flags = SA_SIGINFO;
        act.sa_sigaction = handler;
        sigaction(SIGUSR1, &act, NULL);
        ...
    }
    
    void handler(int signo, siginfo_t *sf, ucontext_t *uc) {
        psiginfo(sf, "...");
        printf("%d\n", sf->si_code);
    }
  • ์ด์ „์˜ ์„ค์ • ๋ณต์›ํ•˜๊ธฐ

    sigaction(SIGTERM, NULL, &oact);
    act.sa_handler = SIG_IGN;
    sigaction(SIGTERM, &act, NULL);
    //do anything
    sigaction(SIGTERM, &oact, NULL);
    #include<signal.h>
    
    static struct sigaction act, oact;
    // SIGTERM : ์†Œํ”„ํŠธ์›จ์–ด ์ข…๋ฃŒ ์‹œ๊ทธ๋„
    // SIGTERM ์„ ์œ„ํ•œ ๊ณผ๊ฑฐ์˜ ํ–‰๋™์„ ๋‚จ๊ฒจ๋‘”๋‹ค
    sigaction(SIGTERM, NULL, &oact);
    // SIGTERM ์„ ์œ„ํ•œ ์ƒˆ๋กœ์šด ํ–‰๋™ ์ง€์ •.
    act.sa_handler = SIG_IGN;
    sigaction(SIGTERM, &act, NULL);
    /* ๋ฌด์–ธ๊ฐ€ ์ž‘์—… */
    // ๊ณผ๊ฑฐ ํ–‰๋™ ๋ณต์›
    sigaction(SIGTERM, &oact, NULL);
  • Alarm signal ์„ค์ •

    • Timer ์‚ฌ์šฉ

      #include <signal.h>
      
      unsigned int alarm(unsigned int secs);
    • unsigned int secs : ์ดˆ ๋‹จ์œ„์˜ ์‹œ๊ฐ„, ์‹œ๊ฐ„ ์ข…๋ฃŒ ํ›„ SIGALRM์„ ๋ณด๋‚ธ๋‹ค

    • alarm์€ exec ํ›„์—๋„ ๊ณ„์† ์ž‘๋™ํ•œ๋‹ค. ํ”„๋กœ๊ทธ๋žจ ๋‚ด์šฉ์€ ๋ณ€ํ•ด๋„ ํ”„๋กœ์„ธ๋Š” ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์—

    • ํ•˜์ง€๋งŒ fork ํ›„์—๋Š” ์ž์‹ process์— ๋Œ€ํ•œ alarm์€ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค. fork๋Š” alarm์„ ์ƒ์†ํ•˜์ง€ ์•Š์Œ

    • ์ฃผ์˜ : alarm(0) ์€ alarm ๋„๊ธฐ. ๋ฐ”๋กœ ์•Œ๋žŒ ๋ณด๋‚ธ๋‹ค๋Š”๊ฑฐ ์•„๋‹˜

    • alarm์€ ๋ˆ„์ ๋˜์ง€ ์•Š์Œ. 2๋ฒˆ ์‚ฌ์šฉ๋˜๋ฉด, ๋‘ ๋ฒˆ์งธ alarm์ด ๋Œ€์ฒด

    • ๋‘ ๋ฒˆ์งธ alarm์˜ return ๊ฐ’์ด ์ฒซ alarm์˜ ์ž”์—ฌ์‹œ๊ฐ„

  • signal blocking

    • ์‚ฌ์šฉ๋ฒ•

      #include <signal.h>
      
      int sigprocmask(int how, const sigset_t *set, sigset_t *oset)
    • oset์€ ๋ด‰์‡„๋œ signal๋“ค์˜ ํ˜„์žฌ mask. ๊ด€์‹ฌ์—†์œผ๋ฉด NULL๋กœ ์ง€์ •

    • ์‹œ๊ทธ๋„ ์ง‘ํ•ฉ์„ ์‚ฌ์šฉํ•ด ํ•œ ๋ฒˆ์— ์—ฌ๋Ÿฌ ์‹œ๊ทธ๋„์„ ๋ธ”๋กํ•  ์ˆ˜ ์žˆ์Œ

      • how : ์‹œ๊ทธ๋„์„ ๋ธ”๋กํ•  ๊ฒƒ์ธ์ง€, ํ•ด์ œํ•  ๊ฒƒ์ธ์ง€ ์—ฌ๋ถ€
      • set : ๋ธ”๋กํ•˜๊ฑฐ๋‚˜ ํ•ด์ œํ•  ์‹œ๊ทธ๋„ ์ง‘ํ•ฉ์˜ ์ฃผ์†Œ
      • oset : NULL ๋˜๋Š” ์ด์ „ ์„ค์ •๊ฐ’์„ ์ €์žฅํ•  ์‹œ๊ทธ๋„ ์ง‘ํ•ฉ์˜ ์ฃผ์†Œ
    • set์— ์ง€์ •ํ•œ ์‹œ๊ทธ๋„ ์ง‘ํ•ฉ์„ ๋ธ”๋กํ•  ๊ฒƒ์ธ์ง€, ํ•ด์ œํ•  ๊ฒƒ์ธ์ง€ how์— ์ง€์ •ํ•ด ํ˜ธ์ถœํ•œ๋‹ค.

      • SIG_BLOCK : set์— ์ง€์ •ํ•œ ์‹œ๊ทธ๋„ ์ง‘ํ•ฉ์„ ์‹œ๊ทธ๋„ ๋งˆ์Šคํฌ์— ์ถ”๊ฐ€ํ•œ๋‹ค. ๋ด‰์‡„ ์ œ๊ฑฐ
      • SIG_UNBLOCK : set์— ์ง€์ •ํ•œ ์‹œ๊ทธ๋„ ์ง‘ํ•ฉ์„ ์‹œ๊ทธ๋„ ๋งˆ์Šคํฌ์—์„œ ์ œ๊ฑฐํ•œ๋‹ค
      • SIG_SETMASK : set์— ์ง€์ •ํ•œ ์‹œ๊ทธ๋„ ์ง‘ํ•ฉ์œผ๋กœ ํ˜„์žฌ ์‹œ๊ทธ๋„ ๋งˆ์Šคํฌ๋ฅผ ๋Œ€์ฒดํ•œ๋‹ค. set์— ์žˆ๋Š” signal๋“ค์„ ์ง€๊ธˆ๋ถ€ํ„ฐ ๋ด‰์‡„
    • set์€ ๋ธ”๋กํ•˜๊ฑฐ๋‚˜ ํ•ด์ œํ•  ์‹œ๊ทธ๋„ ์ง‘ํ•ฉ์„ ๊ฐ€๋ฆฌํ‚ค๊ณ , ์„ธ ๋ฒˆ์งธ ์ธ์ž์ธ oset์€ NULL์ด ์•„๋‹ˆ๋ฉด ์ด์ „ ์„ค์ •๊ฐ’์ด ์ €์žฅ๋œ๋‹ค.

    • ์˜ˆ์ œ

      int main(void) {
        sigset_t new;
      
        sigemptyset(&new);
        sigaddset(&new, SIGINT);
        sigaddset(&new, SIGQUIT);
        sigprocmask(SIG_BLOCK, &new, (sigset_t *)NULL);
      
        printf("Blocking Signals : SIGINT, SIGQUIT\n");
        printf("Send SIGQUIT\n");
        kill(getpid(), SIGQUIT);
      
        printf("Unblocking Signals\n");
        sigprocmask(SIG_UNBLOCK, &new, (sigset_t *)NULL);
      
        return 0;
      }
    • ์˜ˆ์ œ2. input์‹œ interrupt ํ‚ค ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•

      • ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ž…๋ ฅ์„ ๋ฐ›์€ ํ›„์— interrupt ํ‚ค๋Š” ์ƒ๊ด€์ด ์—†์ง€๋งŒ, ์ž…๋ ฅ ๊ธฐ๋‹ค๋ฆด ๋•Œ ctrl+c interrupt ํ‚ค๋ฅผ ๋ˆ„๋ฅด๋ฉด 0์œผ๋กœ ์ž…๋ ฅ์„ ๋ฐ›์•„๋ฒ„๋ฆผ.
      #define BUFSIZE 512
      
      void catchint(int);
      
      int main(int argc, char **argv) {
        int i, j, num[10], sum = 0;
        static struct sigaction act;
      
        act.sa_handler = catchint;
        sigaction(SIGINT, &act, NULL);
      
        for(i=0;i<5;i++) {
          scanf("%d", &num[i]);
          sum += num[i];
          for(j=0;j<=i;j++) {
            printf("...%d\n", num[i]);
            sleep(1);
          }
        }
        exit(0);
      }
      
      void catchint(int signo) {
        printf("DO NOT INTERRUPT ... \n");
      }
      • ๊ทผ๋ฐ scanf๋กœ ์ž…๋ ฅ์„ ๋ฐ›์„ ๋•Œ ctrl+c interruptํ‚ค๋ฅผ block ์‹œ์ผœ์ฃผ๊ณ  ์ž…๋ ฅ์„ ๋ฐ›์€ ํ›„์— ๋‹ค์‹œ ํ’€์–ด์ฃผ๋ฉด ์ œ๋Œ€๋กœ ์ž…๋ ฅ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ
      #define BUFSIZE 512
      
      void catchint(int);
      
      int main(int argc, char **argv) {
        int i, j, num[10], sum = 0;
        static struct sigaction act;
        sigset_t mask;
      
        act.sa_handler = catchint;
        sigaction(SIGINT, &act, NULL);
      
        sigemptyset(&mask);
        sigaddset(&mask, SIGINT);
      
        for(i=0;i<5;i++) {
          sigprocmask(SIG_SETMASK, &mask, NULL);
          scanf("%d", &num[i]);
          sigprocmask(SIG_UNBLOCK, &mask, NULL);
          sum += num[i];
          for(j=0;j<=i;j++) {
            printf("...%d\n", num[i]);
            sleep(1);
          }
        }
        exit(0);
      }
      
      void catchint(int signo) {
        printf("DO NOT INTERRUPT ... \n");
      }
  • pause ์‹œ์Šคํ…œ ์ฝœ

    • ์‚ฌ์šฉ๋ฒ•

      #include <unistd.h>
      int pause(void);
    • signal ๋„์ฐฉ๊นŒ์ง€ ์‹คํ–‰์„ ์ผ์‹œ ์ค‘๋‹จ(CPU ์‚ฌ์šฉ ์—†์ด)

    • signal์ด ํฌ์ฐฉ๋˜๋ฉด ์ฒ˜๋ฆฌ routine ์ˆ˜ํ–‰ & -1 return