2011-03-13 8 views
5

나는 작은 코드를 작성했습니다. 이 코드는 먼저 {SIGSEGV}를 차단 한 다음 SIGRTMIN을 동일한 세트에 추가합니다. 그래서, 최종 신호 세트는 {SIGSEGV, SIGRTMIN}입니다. 따라서, 만약 내가 SIG_UNBLOCK을 사용한다면, SIGRTMIN은 차단 해제되어야하고, 다시 SIG_UNBLOCK을 호출하면 SIGSEGV는 차단 해제되어야한다.sigprocmask()는 UNIX에서 신호를 차단합니다.

즉, 1) {SIGSEGV, SIGRTMIN} 2) SIG_UNBLOCK = SIGRTMIN 차단 해제 3) 다시 SIG_UNBLOCK = SIGSEGV 차단 해제를 호출합니다. 나는 프로세스에게 SIGRTMIN만을 부여하고있다. 따라서 두번째 unblock은 SIGRTMIN으로 프로세스를 정지시켜야한다. 그러나 그렇지 않습니다. 도와주세요. N.B : sigprocmask()에서 다른 질문의 대답에 대한 링크를 제공하지 마십시오. 나는 그것을 보았고 질문을 명확히하지 않습니다.

enter code here 
#include <signal.h> 
#include <unistd.h> 
#include <stdio.h> 

int main() 
{ 
sigset_t old_set,new_set; 
sigemptyset(&old_set); 
sigemptyset(&new_set); 

if(sigaddset(&old_set,SIGSEGV)==0) 
{ 
    printf("sigaddset successfully added for SIGSEGV\n"); 
} 
sigprocmask(SIG_BLOCK,&old_set,NULL); // SIGSEGV signal is masked 
kill(0,SIGSEGV); 


//***************************************************************** 

if(sigaddset(&new_set,SIGRTMIN)==0) 
{ 
    printf("sigaddset successfully added for SIGRTMIN\n"); 
} 
    sigprocmask(SIG_BLOCK,&new_set,&old_set); // SIGRTMIN signal is masked 
kill(0,SIGSEGV); 

//****************** Unblock one signal at a time ****************** 

sigprocmask(SIG_UNBLOCK,&new_set,&old_set); // SIGRTMIN signal is unmasked 
sigprocmask(SIG_UNBLOCK,&new_set,&old_set); // SIGSEGV signal is unmasked 

}

Output: 
[[email protected] signals]# ./a.out 
    sigaddset successfully added for SIGSEGV 
    sigaddset successfully added for SIGRTMIN 
    (Note:SIGSEGV is not received even after sigprocmask(SIG_UNBLOCK,&new_set,&old_set); a second time) 

답변

11

귀하의 전제는 잘못된 것입니다. sigprocmask이라는 단일 호출로 전체 세트가 차단되고 차단 해제됩니다.

또한 일반적으로 차단하려는 모든 신호가 들어있는 세트를 만들고 나서 모두 sigprocmask(SIG_BLOCK, pointer_to_sigset);으로 차단하려고 시도합니다.

당신의 코드는 실제로 SIGSEGV를 차단하지 않습니다. 다음은 스 니펫을 불필요하게 길게 만들므로 오류 처리없이 작성하는 것입니다. 하지만, 가능한 오류의 목록은 man 페이지에서 제공하는 오류 모든 기능 을 확인합니다

물론
/* ... */ 
sigset_t signal_set; /* We don't need oldset in this program. You can add it, 
         but it's best to use different sigsets for the second 
         and third argument of sigprocmask. */ 
sigemptyset(&signal_set); 

sigaddset(&signal_set, SIGSEGV); 
sigaddset(&signal_set, SIGRTMIN); 

/* now signal_set == {SIGSEGV, SIGRTMIN} */ 

sigprocmask(SIG_BLOCK, &signal_set, NULL): /* As i said, we don't bother with the 
               oldset argument. */ 

kill(0,SIGSEGV); 
kill(0,SIGSEGV); /* SIGSEGV is not a realtime signal, so we can send it twice, but 
        it will be recieved just once */ 

sigprocmask(SIG_UNBLOCK, &signal_set, NULL); /* Again, don't bother with oldset */ 

/* SIGSEGV will be received here */ 

, 별도의 세트에 두 운영에 신호를 차단 분할 할 수 있습니다. 이 메커니즘은 다음과 같이 작동합니다. 차단 된 신호 집합이 있습니다. 이전 세트 인수를 제공 한 경우 이전 집합을 대체합니다. 해당 세트에 SIG_BLOCK으로 추가하고 SIG_UNBLOCK을 사용하여 해당 세트를 제거하고 sigprocmask 함수의 SIG_SETMASK 인수로 전체 세트를 원하는대로 변경할 수 있습니다.

+0

@kubi : 왜 SIGSEGV를 수신하지 못합니까? – kingsmasher1

+0

@ kubi : 아니요. 전체 세트가 한 번에 차단 해제되지 않는다고 생각합니다. 링크 (http://stackoverflow.com/questions/25261/help-with-sigprocmask)를 확인하십시오. 게다가 sigprocmask() 자체는 블로킹이나 블럭킹을하지 않으므로 블럭킹, 블럭킹 또는 마스크를 수행하는 인자 또는 첫 번째 매개 변수입니다. 그래서 제 잘못을 지적하기 전에 생각하십시오. – kingsmasher1

+0

@ kingsmasher1 : 어떻게'SIGSEGV'를 다루고 있습니까? 신호 처리기 코드 스 니펫을 붙여 넣을 수 있습니까? 신호가 올바르게 전송됩니까? 'sigprocmask'와'kill'의 에러 코드를 확인하십시오. – kubi

0

kubi가 지적한 바 : 수정 된 코드입니다. 문제는 바로 old_set과 new_set입니다. SIGSEGV는 차단 해제되지 않은 old_set에 추가되어 Segmentation fault (SIGSEGV 신호)를받지 못했습니다. kubi에게 감사드립니다.

enter code here 
#include <signal.h> 
#include <unistd.h> 
#include <stdio.h> 

int main() 
{ 
sigset_t old_set,new_set; 
sigemptyset(&old_set); 
sigemptyset(&new_set); 

if(sigaddset(&old_set,SIGSEGV)==0) 
{ 
    printf("sigaddset successfully added for SIGSEGV\n"); 
} 
sigprocmask(SIG_BLOCK,&new_set,&old_set); // SIGSEGV signal is masked 
kill(0,SIGSEGV); 


//***************************************************************** 

if(sigaddset(&new_set,SIGRTMIN)==0) 
{ 
    printf("sigaddset successfully added for SIGRTMIN\n"); 
} 
if(sigprocmask(SIG_BLOCK,&new_set,&old_set)==-1) // SIGRTMIN signal is masked 
{ 
    perror("sigprocmask"); 
} 
kill(0,SIGSEGV); 


//****************** Unblock all signals ****************** 

if(sigprocmask(SIG_UNBLOCK,&new_set,&old_set)==-1) // SIGRTMIN signal is unmasked 
{ 
    perror("sigprocmask"); 
} 
}