답변:
"너무 많은 신호"문제 외에도 신호를 명시 적으로 무시할 수 있습니다. 보낸 사람 man 2 signal
:
If the signal signum is delivered to the process, then one of the
following happens:
* If the disposition is set to SIG_IGN, then the signal is ignored.
신호도 차단할 수 있습니다. 부터 man 7 signal
;
A signal may be blocked, which means that it will not be delivered
until it is later unblocked. Between the time when it is generated
and when it is delivered a signal is said to be pending.
차단 된 신호 세트와 무시 된 신호 세트는 모두 하위 프로세스에 의해 상속되므로 애플리케이션의 상위 프로세스가 이러한 신호 중 하나를 무시하거나 차단했을 수 있습니다.
프로세스가 이전 신호 처리를 완료하기 전에 여러 신호가 전달되면 어떻게됩니까? OS에 따라 다릅니다. signal(2)
나와 그것을 위에 링크 된 맨 페이지 :
libc
있지만 BSD 동작을 기대합니다.전송 된 모든 신호가 전달 될 것이라고 믿을 수 없습니다. 예를 들어, 종료 된 자식 프로세스에서 SIGCHLD를 처리하는 데 시간이 오래 걸리는 경우 Linux 커널은 SIGCHLD를 "응집" 합니다.
질문의 다른 부분에 대답하기 위해, 여러 다른 신호가 너무 짧은 간격으로 도착하면 신호가 커널 내부에서 "큐잉"됩니다.
sigaction()
의 sa_sigaction
멤버로 신호 핸들러를 siginfo_t
설정 sa_mask
하고 siginfo_t
인수 멤버를 신중하게 설정하는 데 사용해야 합니다 . 나는 이것이 모든 "비동기"신호를 마스킹하는 것을 의미한다고 생각한다. Linux 매뉴얼 페이지에 따르면 sigaction()
처리중인 신호를 가리게됩니다. sa_flags
멤버를 SA_SIGINFO로 설정해야한다고 생각 하지만 왜이 미신이 있는지 기억이 나지 않습니다. 나는 이것이 경쟁 조건없이 설정 상태를 유지하고 대부분의 다른 신호에 의해 방해받지 않는 신호 핸들러를 프로세스에 제공 할 것이라고 믿습니다.
신호 처리기 함수를 매우 신중하게 작성하십시오. 기본적으로 신호가 포착되었음을 나타내는 전역 변수를 설정하고 나머지 프로세스가 해당 신호에 대해 원하는 동작을 처리하도록합니다. 그런 식으로 신호가 최소 시간 동안 마스크됩니다.
또한 신호 처리 코드를 매우 철저히 테스트해야합니다. 작은 테스트 프로세스에 넣고 2 ~ 3 개의 특수 목적 신호 전송 프로그램에서 가능한 한 많은 SIGUSR1 및 SIGUSR2 신호를 보냅니다. 코드가 SIGUSR1 및 SIGUSR2를 신속하고 정확하게 처리 할 수 있다고 확신 한 후에 다른 신호도 혼합하십시오. 어려운 디버깅에 대비하십시오.
Linux 만 사용하고 Linux 만 사용하는 경우 해당 신호를 수신하기 위해 폴링하거나 폴링 signalfd()
할 파일 디스크립터를 작성하는 방법 에 대해 생각할 수 있습니다 select()
. 를 사용 signalfd()
하면 디버깅이 쉬워 질 수 있습니다.
프로세스가 성공적으로 호출되면 신호가 전달됩니다. kill
그러면 대상이 신호를 수신합니다. 이것은 비동기 적입니다. 발신자는 신호 수신 또는 처리시기를 알 수 없습니다. 그러나 이것이 신호가 전달되는 것을 보장하지는 않습니다. 신호를 처리하기 전에 대상이 죽을 수 있습니다. 대상이 전달 될 때 신호를 무시하는 경우 신호가 적용되지 않습니다. 대상이 처리하기 전에 동일한 신호 번호의 여러 인스턴스를 수신하는 경우 신호가 병합 될 수 있으며 일반적으로 처리됩니다. 동일한 신호를 프로세스에 두 번 보내면 프로세스가 신호를 수신하는지 알 수 없습니다 한번 아니면 두번. 신호는 주로 프로세스를 중단 시키거나 프로세스가주의를 기울 이도록하는 방식으로 설계되었으므로 통신용으로 설계되지 않았습니다.
안정적인 전달이 필요한 경우 다른 통신 메커니즘이 필요합니다. 프로세스 사이에는 두 가지 주요 통신 메커니즘이 있습니다. 파이프 는 단방향 통신을 허용합니다. 소켓은 양방향 통신과 같은 서버에 여러 연결을 할 수 있습니다. 전송하는 알림 수만큼 대상을 처리하기 위해 대상이 필요한 경우 파이프를 통해 바이트를 전송하십시오.
커널은 차단 된 상태에서 둘 이상이 전달되면 표준 신호를 자유롭게 통합 할 수 있습니다. 반면에 실시간 신호는 유사하게 장애가 없습니다.
에서 신호 (7) 매뉴얼 페이지 :
실시간 신호는 다음과 같이 구별됩니다.
- 실시간 신호의 여러 인스턴스가 대기열에있을 수 있습니다. 반대로, 해당 신호가 현재 차단 된 상태에서 표준 신호의 여러 인스턴스가 전달되면 하나의 인스턴스 만 대기합니다.
SIGRTMIN ~ SIGRTMAX 범위의 숫자가있는 신호를 사용해보십시오.
ulimit -i
Ubuntu 18.04에서이 값을 63432로 표시합니다.
signal(2)
에이 혼동을 피할 것을 강력하게 제안sigaction(2)
합니다.