2013-06-22 2 views
4

signal (3)을 사용하여 실행중인 OS에서 사용할 수있는 모든 신호에 대해 신호 처리기를 등록하려면 어떻게합니까?모든 신호에 대한 신호 처리기

내 코드는 다음과 같습니다

void sig_handler(int signum) 
{ 
    printf("Received signal %d\n", signum); 
} 


int main() 
{ 
    signal(ALL_SIGNALS_??, sig_handler); 
    while (1) { 
     sleep(1); 
    }; 
    return 0; 
} 
+3

for 루프에서, 1에서 31까지? –

+4

각 시스템에는 신호 목록이 있습니다. '/ usr/include/signal.h'를보십시오. 모든 것을 나타 내기 위해 사용할 수있는 단일 표준 매크로는 없습니다. 을 더한. 예를 들어'SIGKILL '을 모두 잡을 수는 없습니다. –

+0

예, 이미 언급했습니다. 하지만 일부 mordern OS에서는 32 이상이 있습니다. FreeBSD에서 kill -l은 예를 들어 126 개 항목을 반환합니다. – kober

답변

5

대부분의 시스템이 가지고 매크로 NSIG 또는 _NSIG (는 네임 스페이스를 위반하기 때문에 전자가 표준 준수 모드에서 사용할 수 없습니다 것) signal.h 같은 그 루프에 정의 for (i=1; i<_NSIG; i++)은 모든 신호를 처리합니다. 또한 신호 마스크가있는 POSIX 시스템에서 CHAR_BIT*sizeof(sigset_t)NSIG 또는 _NSIG이 정의되지 않은 경우 폴백으로 사용할 수있는 신호 수의 상한선입니다.

3

신호 처리기는 재진입 문제 및 기타 문제를 처리해야합니다. 실제로는 신호를 마스크 한 다음 수시로 검색하는 것이 더 편리합니다. 이와 (어쨌든 처리 할 수 ​​SIGSTOPSIGKILL 제외) 모든 신호를 마스크 할 수 있습니다 : 당신의 pthreads를 사용하는 경우

sigset_t all_signals; 
sigfillset(&all_signals); 
sigprocmask(SIG_BLOCK, &all_signals, NULL); 

코드는 약간 다릅니다. 당신이 그 일을하면

sigset_t all_signals; 
sigfillset(&all_signals); 
pthread_sigmask(SIG_BLOCK, &all_signals, NULL); 

, 당신은 정기적으로이 같은 sigtimedwait(2)를 호출해야합니다 :

struct timespec no_time = {0, 0}; 
siginfo_t result; 
int rc = sigtimedwait(&all_signals, &result, &no_time); 

당신은 어떤 다른 사람을 만들기 전에 메인 스레드에서 (바람직하게는) 모든 스레드에서이 전화, 또는 보류중인 신호가 있습니다. 이에 대한 정보는 result에 있으며 rc은 신호 번호가됩니다. 그렇지 않은 경우 rc은 -1이되고 errnoEAGAIN이됩니다. select(2)/poll(2) (예 : 일부 이벤트 중심 시스템의 일부)을 이미 호출 한 경우 signalfd(2)을 생성하고 이벤트 루프에 첨부 할 수 있습니다. 이 경우 위에 나온 것처럼 신호를 마스킹해야합니다.