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
]$
'컴퓨터 > 프로그래밍' 카테고리의 다른 글
C언어 kill 시그널 전송 함수 kill() (0) | 2020.03.15 |
---|---|
C언어 시그널 처리 방법을 설정 함수 signal() (0) | 2020.03.15 |
C언어 지정한 시간만큼 대기 함수 sleep() (0) | 2020.03.15 |