시그널에 대한 더 많은 정보를 담은 리눅스 교재를 배포했습니다. 아래의 페이지에서 리눅스 교재를 받아가세요.

https://reakwon.tistory.com/233

 

리눅스 프로그래밍 note 배포

티스토리에 리눅스에 관한 내용을 두서없이 여지껏 포스팅했었데요. 저도 제 포스팅을 찾기가 어렵기도 하고 티스토리에서 코드삽입을 하게 되면 이게 일자로 쭉 쓰여져있는 x같은 현상이 생겨

reakwon.tistory.com

 

시그널에 대해서 이야기하는 3번째 시간이 되겠네요. 지난 번에는 시그널 개념과 시그널 관련함수까지 다루어 봤습니다. 

시그널 개념과 시그널 핸들러와 시그널 관련 함수(sigfillset, sigemptyset, sigaddset, sigdelset, sigprocmask)는 지난 번 포스팅을 참고하시기 바랍니다.

 

이번에는 시그널에 대한 sigpending과 sigismember에 대해서 알아보도록 하겠습니다.

  •  sigpending
int sigpending(sigset_t *set);

 

현재 블록되어 대기중인 signal들을 set에 담게 됩니다. 만일 블록될 signal들이 {SIGINT, SIGTSTP} 라고 하고 SIGTSTP가 블록된 상태라면 set에는 {SIGTSTP}가 들어가게 되지요. 이 함수가 성공했다면 0, 실패했다면 -1을 반환합니다.

  • sigisempty
int sigismember(sigset_t *set, int signo);

 

현재 set에 signo(시그널 번호)가 포함되어 있는지 알아냅니다. 만약 set에 해당하는 시그널 번호가 존재한다면 1, 없다면 0을 반환하게 됩니다. -1을 반환할때도 있는데 이 경우는 시그널을 확인할 수 없다는 의미랍니다. 간단하죠?

 

이제 간단하게 예제를 보도록 합시다.

 

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

int main(){
        sigset_t pendingset;
        sigset_t set;

        sigemptyset(&set);
        sigemptyset(&pendingset);

        sigaddset(&set,SIGQUIT);
        sigaddset(&set,SIGINT);
        sigaddset(&set,SIGTSTP);

        sigprocmask(SIG_BLOCK,&set,NULL);

        printf("SIGQUIT, SIGINT, SIGTSTP를 발생시켜보세요.\n");
        sleep(3);

        if(sigpending(&pendingset)==0){
                printf("\n\nBlock되어 대기중인 SIGNAL\n");
                if(sigismember(&pendingset,SIGQUIT))
                        printf("SIGQUIT\n");
                if(sigismember(&pendingset,SIGINT))
                        printf("SIGINT\n");
                if(sigismember(&pendingset,SIGTSTP))
                        printf("SIGTSTP\n");
        }

        sleep(3);

        sigprocmask(SIG_UNBLOCK,&set,NULL);

        printf("SIGQUIT OR SIGINT OR SIGTSTP 신호를 발생시켰으면 이 메
시지가 보이지 않습니다.\n");
        return 0;
}

이 프로그램은 set에 있는 시그널들이 발생하면 블록하고 만약 이 중 시그널이 발생하면 블록된 시그널의 목록을 보여주는 프로그램입니다. 우선 set에는 SIGQUIT, SIGINT, SIGTSTP라는 시그널이 들어있고 sigprocmask로 블록시키라고 명령합니다. 이 후 3초가 지난후 sigpending으로 블록되어 대기중인 signal을 pendingset에 설정합니다. 함수가 성공적으로 호출되었다(반환값 0)면 sigismember에서 어떤 시그널이 대기중인지 확인합니다.

 

확인해봅시다. gcc 소스코드 -o signal 로 컴파일하고 실행파일을 실행시켜봅시다.

# ./signal

SIGQUIT, SIGINT, SIGTSTP를 발생시켜보세요.

^C^Z

Block되어 대기중인 SIGNAL

SIGINT

SIGTSTP

저는 3초이내 Ctrl+C(SIGINT)와 Ctrl+Z(SIGTSTP)를 발생시키고 메시지를 확인해보니 SIGINT와 SIGTSTP가 대기중이라고 나옵니다. 이해되셨나요?

 

  •  sigsuspend
int sigsuspend(const sigset_t *mask);

시그널을 BLOCK시킴과 동시에 대기합니다. sigprocmask같은 경우 how를 SIG_BLOCK이나 SIG_SETMASK로 설정하면 블록하기만 할뿐 대기하지는 않는데, sigsuspend는 블록과 대기를 동시에 할 수 있는 것이죠. 성공시 0, 실패시 -1을 반환합니다.

아래의 예제가 있습니다.

 

 

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

int main(){    
        sigset_t set;    
   
        sigemptyset(&set);   
 
        sigaddset(&set,SIGQUIT);   
        sigaddset(&set,SIGINT); 
        sigaddset(&set,SIGTSTP);   
 
        printf("SIGQUIT, SIGINT, SIGTSTP이 5초간 BLOCK됩니다.\n");  
 
        sigprocmask(SIG_SETMASK,&set,NULL);    
   
        sleep(5);     
        printf("\n\nSIGNAL 블록이 해제되고 시그널이 발생했다면 종료됩니다.\n");        
        printf("시그널을 발생시키지 않았다면 발생시켜 종료하세요.\n");      
        sigemptyset(&set);      
        sigsuspend(&set);   
  
        return 0;
}


SIGQUIT, SIGINT, SIGTSTP를 sigprocmask의 SIG_SETMASK로 블록시키려고 하는군요. 5초 후에 set을 빈 집합으로 설정합니다. 만일 SIGQUIT, SIGINT, SIGTSTP가 5초 이내에 발생했다면 프로그램은 5초후 바로 종료하게 되고, 발생시키지 않았다면 위 3개의 시그널이 발생할때까지 대기하게 되는 것입니다.

  •  5초 내에 SIGINT 신호를 전달한 경우 5초가 지난 후 메시지 출력후 바로 종료
# ./a.out 
SIGQUIT, SIGINT, SIGTSTP이 5초간 BLOCK됩니다.
^C

SIGNAL 블록이 해제되고 시그널이 발생했다면 종료됩니다.
시그널을 발생시키지 않았다면 발생시켜 종료하세요.
  • 5초내에 3개의 신호 아무것도 를 주지 않은 경우 신호를 줄때까지 계속 대기 
# ./a.out 
SIGQUIT, SIGINT, SIGTSTP이 5초간 BLOCK됩니다.


SIGNAL 블록이 해제되고 시그널이 발생했다면 종료됩니다.
시그널을 발생시키지 않았다면 발생시켜 종료하세요.

 

이상으로 3개의 signal 관련 함수를 알아보았습니다.

 

반응형
블로그 이미지

REAKWON

와나진짜

,