2011-12-28 4 views
2

만 그들 중 두 사람은 처리 될 것이며 나머지는 무시됩니다두 개 이상의 연속 된 신호를 잡는 방법? 나는 다음과 같은 프로그램에 여러 후속 <code>Hangup</code> 신호를 보낼 경우

:

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

int id; 
void handler(int s) 
{ 
    id++; 
    int i; 
    for(i=0; i<3; i++) 
    { 
     printf("Sig %d\n", id); 
     sleep(2); 
    } 
} 

int main() 
{ 
    int i; 
    signal(SIGHUP, handler); 
    for(i=0; ; i++) 
    { 
     printf("%d\n", i); 
     sleep(1); 
    } 
    return 0; 
} 

내가 프로세스에 신호를 보내려면 다음 명령을 사용하여 내가 세 번 연속해서 위의 명령을 실행하면

kill -l {#process} 

, 제 3 신호는 다음과 같은 출력에서 ​​무시됩니다

0 
1 
2 
3 
4 
5 
6 
7 
Sig 1 
Sig 1 
Sig 1 
Sig 2 
Sig 2 
Sig 2 
8 
9 
10 
11 
12 

세 번째 신호도 잡을 방법이 있습니까?

+2

신호 처리기 내에서 잠자기는 의심 스럽습니다. 거기에 있어야합니까? – wallyk

+0

@wallyk 매뉴얼 페이지에 따르면, POSIX.1-2004는 시그널 핸들러 내에서 'sleep'을 안전하게 요구한다. –

+0

정상 신호가 대기열에 들어 가지 않으면 어떤 작업을 하던지 놓치게됩니다. – nos

답변

2

일반적으로 표준 신호로는이를 수행 할 수 없습니다. 유닉스 커널은 일반적으로 보류중인 신호를 대기열에 넣는다. Sig1과 Sig3이 Sig1 처리기에서 잠자는 동안 전송되면 병합됩니다.

sigaction (2)을 사용하여 신호 처리기를 설정하고 SA_NODEFER 플래그를 제공 할 수 있습니다. 신호 처리기에서 새로운 신호를 전달할 수 있습니다. 처리기가 재 입력되었는지 확인하십시오. 오류가 발생하기 쉬운 솔루션입니다.

또한 "실시간 신호"라고하는 POSIX.1b (POSIX.1-2001) 확장이 있습니다. 이러한 신호는 여러 번 대기 할 수 있지만 SIGHUP은 그 중 하나가 아닙니다. signal (7)은 실시간 신호가 33 (SIGRTMIN)에서 64 (SIGRTMAX)로 번호가 매겨 졌다고 리눅스에서 밝힌다.

1

Linux에서 보류중인 신호는 단 하나의 비트로 표시됩니다. 즉, 핸들러가 이미 실행 중일 때 여러 신호가 생성되면 다시 한 번만 호출됩니다.

+0

필자가 리눅스에서'ulimit -a'를 입력하면,'pending signals'에 기본값 16383이 있다는 것을 알 수 있습니다.'getrlimit'과 리소스 이름'RLIMIT_SIGPENDING' (다시 16383)으로 테스트했습니다. 그렇다면 리눅스가 보류중인 신호를 단 한 비트 만 처리하는 방법은 무엇입니까? – saeedn

+0

@saeedn 프로세스 당 사용자 당 보류 될 수있는 총 신호 수 (실제로 "실제 사용자 ID"당)입니다. 단일 신호의 경우, 프로세스 당 하나의 신호 만 보류 될 수 있습니다. –