본문으로 바로가기
homeimage
  1. Home
  2. 컴퓨터/프로그래밍
  3. C언어 시그널 처리 함수 sigaction()

C언어 시그널 처리 함수 sigaction()

· 댓글개 · 바다야크

C함수 시그널 처리 sigaction()

sigaction() 함수는 signal()보다 향상된 기능을 제공하는 시그널 처리를 결정하는 함수입니다.

  • 헤더: signal.h
  • 형태: int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
  • 인수: int signum 시그널 번호
    struct sigaction *act 설정할 행동. 즉, 새롭게 지정할 처리 행동
    struct sigaction *oldact 이전 행동, 이 함수를 호출하기 전에 지정된 행동 정보가 입력됩니다.
  • 반환: int 0 == 성공, -1 == 실패

signal()에서는 처리할 행동 정보로 시그널이 발생하면 호출이될 함수 포인터를 넘겨 주었습니다. 그러나 sigaction()에서는 struct sigaction 구조체 값을 사용해서 좀 더 다양한 지정이 가능합니다.

struct sigaction {
    void (*sa_handler)(int);    // 시그널을 처리하기 위한 핸들러. 
                                // SIG_DFL, SIG_IGN 또는 핸들러 함수
    void (*sa_sigaction)(int, siginfo_t *, void *); // 밑의 sa_flags가 SA_SIGINFO일때
                                                    // sa_handler 대신에 동작하는 핸들러
    sigset_t sa_mask;             // 시그널을 처리하는 동안 블록화할 시그널 집합의 마스크
    int sa_flags;                 // 아래 설명을 참고하세요.
    void (*sa_restorer)(void);    // 사용해서는 안됩니다.
}

ss_flgs는 아래와 같은 값이 사용되며 OR 연산자로 여러 개를 동시에 지정하여 사용할 수 있습니다.

옵션 의미
SA_NOCLDSTOP signum이 SIGCHILD일 경우, 자식 프로세스가 멈추었을 때, 부모 프로세스에 SIGCHILD가 전달되지 않는다.
SA_ONESHOT 시그널을 받으면 설정된 행도을 취하고 시스템 기본 설정인 SIG_DFL로 재설정된다.
SA_RESETHAND
SA_RESTART 시그널 처리에 의해 방해 받은 시스템 호출은 시그널 처리가 끝나면 재시작한다.
SA_NOMASK 시그널을 처리하는 동안에 전달되는 시그널은 블록되지 않는다.
SA_NODEFER
SA_SIGINFO 이 옵션이 사용되면 sa_handler대신에 sa_sigaction이 동작되며, sa_handler 보다 더 다양한 인수를 받을 수 있습니다. sa_sigaction이 받는 인수에는 시그널 번호, 시그널이 만들어진 이유, 시그널을 받는 프로세스의 정보입니다.

C언어 sigaction() 함수 예제 1

signal()을 이용하여 Ctrl-C 를 누르면 사용자 핸들러가 실행되었다가 두 번째 Ctrl-C 키를 누르면 프로그램이 종료되는 예제입니다.

#include <stdio.h>
#include <unistd.h>
#include <signal.h>

struct sigaction act_new;
struct sigaction act_old;

void sigint_handler( int signo)
{
   printf( "Ctrl-C 키를 눌루셨죠!!\n");
   printf( "또 누르시면 종료됩니다.\n");
   sigaction( SIGINT, &act_old, NULL);
}

int main( void)
{
   
   act_new.sa_handler = sigint_handler; // 시그널 핸들러 지정
   sigemptyset( &act_new.sa_mask);      // 시그널 처리 중 블록될 시그널은 없음
                                           
   // SIGINT를 지정하면서 act_old에 이전 정보를 구합니다.                                           
   sigaction( SIGINT, &act_new, &act_old); 
   while( 1 ){
      printf( "badayak.com\n");
      sleep( 1);
   }
}

C언어 sigaction() 예제 실행 결과

]$ ./a.out
badayak.com
badayak.com
badayak.com
^CCtrl-C 키를 눌루셨죠!!
또 누르시면 종료됩니다.
badayak.com
badayak.com
^C
]$

C언어 sigaction() 함수 예제 2

sigaction()에서는 시그널 발생하여 처리 중일 때에는 다른 시그널이 발생하더라도 블록이 되도록 지정할 수 있습니다. Ctrl-C 키를 누르면 3초간 대기하도록 하고, 이때 프로그램을 종료시키는 또 다른 키인 Ctyrl-Z를 누르면 어떻게 되는지 확인해 보는 예제입니다.

#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void sigint_handler( int signo)
{
   int   ndx;

   printf( "Ctrl-C 키를 눌루셨죠.\n");
   printf( "3초간 대기하겠습니다. 이때 Ctrl-Z키를 눌러 주세요.\n");

   for ( ndx = 3; 0 < ndx; ndx--){
      printf( "%d 초 남았습니다.\n", ndx);
      sleep( 1);
   }
}

int main( void)
{
   struct sigaction act;

   act.sa_handler = sigint_handler;  // 시그널 핸들러 지정
   sigfillset( &act.sa_mask);        // 모든 시그널을 블록

   sigaction( SIGINT, &act, NULL);
   while(1 ){
      printf( "badyak.com\n");
      sleep( 1);
   }
}

C언어 sigaction() 예제 실행 결과

]$ ./a.out
badyak.com
badyak.com
^CCtrl-C 키를 눌루셨죠.
3초간 대기하겠습니다. 이때 Ctrl-Z키를 눌러 주세요.
3 초 남았습니다.
2 초 남았습니다.
1 초 남았습니다.
^CCtrl-C 키를 눌루셨죠.
3초간 대기하겠습니다. 이때 Ctrl-Z키를 눌러 주세요.
3 초 남았습니다.
2 초 남았습니다.
1 초 남았습니다.
^Z
[1]+  정지됨               ./a.out
]$
SNS 공유하기
💬 댓글 개
최근글
이모티콘창 닫기
울음
안녕
감사해요
당황
피폐

이모티콘을 클릭하면 댓글창에 입력됩니다.