2011-08-26 4 views
1

나는 만료시 RT 신호를 던지는 간단한 타이머를 구현 중이다. 내가하고 싶은 것은 시그널이 발생할 때 호출되는 시그널 핸들러 (sigaction 사용)를 등록하는 것이다. 한편 메인 코드는 sigwaitinfo를 사용하여 신호가 호출 될 때까지 대기합니다.커스텀 sigaction 시그널 핸들러와 pthread_sigmask를 모두 사용할 수 있습니까?

신호 처리기 또는 sigwaitinfo 중 하나만 구현하면 정상적으로 작동합니다. 그러나 둘 다 사용되면 신호 처리기가 호출되지 않습니다. 나는 순서를 바꾸려고 노력했다. 즉 신호를 차단하기 전에 핸들러를 등록한다. 차이는 없습니다. 내가 스레드/전송 내가 스레드를 사용하는 것으로 차단하는 방법에 대한 가능한 한 많이 배울 필요가 있기 때문에

여기, 내가 주로 교육 목적을 위해이 일을하고있는 코드

// gcc -Wall -o sigwait_example sigwait_example.c -lrt 
#include <stdlib.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <signal.h> 
#include <time.h> 
#include <errno.h> 
#include <string.h> 

#define install_handler(sig,sa) if(sigaction(sig, &sa, NULL) == -1){ \ 
            perror("sigaction"); } 
#define SIG SIGRTMIN+1 

volatile int flag=0; 

void handler(int signum){ 
    flag++; 
} 

int main(void){ 
    struct itimerspec its; 
    sigset_t blocked; 
    siginfo_t si; 
    timer_t timerid; 
    struct sigevent evt; 
    struct sigaction sa; 

    evt.sigev_notify = SIGEV_SIGNAL; 
    evt.sigev_signo = SIG; 
    evt.sigev_value.sival_ptr = &timerid; 
    if (timer_create(CLOCK_REALTIME, &evt, &timerid)){ 
     perror("timer_create"); 
    } 

    //setup timer 
    its.it_value.tv_sec = 0; 
    its.it_value.tv_nsec = 0.1*1E9; 
    its.it_interval.tv_sec = 0; 
    its.it_interval.tv_nsec = 0; 

    //arm the timer 
    if (timer_settime(timerid, 0, &its, NULL)) 
     perror("timer_settime"); 

    sigemptyset(&blocked); 
    sigaddset(&blocked, SIG); 
    //add SIG to blocked signals 
    pthread_sigmask(SIG_BLOCK, &blocked, NULL); 

    sa.sa_flags = SA_SIGINFO; //use this flag to set custom handler 
    sa.sa_sigaction = handler; 
    sigemptyset(&sa.sa_mask); 
    install_handler(SIG,sa); 

    while (sigwaitinfo(&blocked, &si) == -1 && errno == EINTR); 
    printf("received signal: %s, flag=%d\n",strsignal(si.si_signo),flag);  
    //while(flag==0) sleep(1); //use this when only signal handler is used 

    timer_delete(timerid); 

    return 0; 
} 

입니다.

답변

1

sigwaitinfo()이 대기열에서 신호를 제거하기 때문에 불가능합니다.

그러나이 신호의 sigaction 구조체를 검색하고 처리기를 실행하려면 sigaction(SIG, NULL, &sa)을 사용할 수 있습니다.

+0

흠, 답변 해 주셔서 감사합니다. 내가 처리기를 실행하기 위해 struct sigaction을 어떻게 사용하는지 이해하지 못하겠습니까? – user460880

+0

그것은 함수에 대한 포인터와 필요한 모든 것을 가지고 있습니다. – arnaud576875

+1

그리고 가장 좋은 점은 ... 포인터가'SIG_DFL'이라면, 호출하려고 할 때 신호의 기본 동작에 꽤 가깝게됩니다. :-) –

관련 문제