신호를 무시할 수 있습니까 (손실)?


9

신호 (일부 SIGUSR1 / SIGUSR2 / SIGSTOP)를 통해 근로자와 통신하는 응용 프로그램이 있습니다.

모든 신호가 처리기에 의해 전달되고 처리 될 것이라는 것을 믿을 수 있습니까?

애플리케이션이 신호를 처리 할 수없는 것보다 신호가 더 빨리 전송되면 (예 : 현재 높은 호스트로드로 인해) 어떻게됩니까?

답변:


8

"너무 많은 신호"문제 외에도 신호를 명시 적으로 무시할 수 있습니다. 보낸 사람 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)나와 그것을 위에 링크 된 맨 페이지 :

  • 시스템 V는 신호 배치를 기본값으로 재설정합니다. 게다가 여러 신호를 빠르게 전달하면 재귀 (?) 호출이 발생합니다.
  • BSD는 핸들러가 완료 될 때까지 신호를 자동으로 차단합니다.
  • 리눅스에서 이것은 GNU 용으로 설정된 컴파일 플래그에 달려 libc있지만 BSD 동작을 기대합니다.

4
Linux 매뉴얼 페이지는 대신 signal(2)에이 혼동을 피할 것을 강력하게 제안 sigaction(2)합니다.
Nate Eldredge

7

전송 된 모든 신호가 전달 될 것이라고 믿을 수 없습니다. 예를 들어, 종료 된 자식 프로세스에서 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()하면 디버깅이 쉬워 질 수 있습니다.


2
통합되는 것은 SIGCLD만이 아니라 모든 신호가 처리되기 전에 전달되면 통합 될 수 있습니다.
Gilles 'SO- 악마 그만'

SIGCHLD 신호에 대한 "너무 긴"측정 기준이 있습니까? 현재 내 프로그램 에서이 동작이 발생하고 있으며 신호 처리기는 ~ 100ms 이상 걸리지 않습니다.
xrisk

@Rishav-내 지식으로는 "너무 긴"것이 무엇인지 알 방법이 없습니다. 전반적인 시스템로드가 중요하다고 생각합니다. 즉, 다른 프로세스와 커널이 수행하는 작업은 신호가 통합되는 신호 사이의 "시간"에 영향을 미칩니다. 도움이되지 않는 답변이라고 생각합니다.
Bruce Ediger

6

프로세스가 성공적으로 호출되면 신호가 전달됩니다. kill그러면 대상이 신호를 수신합니다. 이것은 비동기 적입니다. 발신자는 신호 수신 또는 처리시기를 알 수 없습니다. 그러나 이것이 신호가 전달되는 것을 보장하지는 않습니다. 신호를 처리하기 전에 대상이 죽을 수 있습니다. 대상이 전달 될 때 신호를 무시하는 경우 신호가 적용되지 않습니다. 대상이 처리하기 전에 동일한 신호 번호의 여러 인스턴스를 수신하는 경우 신호가 병합 될 수 있으며 일반적으로 처리됩니다. 동일한 신호를 프로세스에 두 번 보내면 프로세스가 신호를 수신하는지 알 수 없습니다 한번 아니면 두번. 신호는 주로 프로세스를 중단 시키거나 프로세스가주의를 기울 이도록하는 방식으로 설계되었으므로 통신용으로 설계되지 않았습니다.

안정적인 전달이 필요한 경우 다른 통신 메커니즘이 필요합니다. 프로세스 사이에는 두 가지 주요 통신 메커니즘이 있습니다. 파이프 는 단방향 통신을 허용합니다. 소켓은 양방향 통신과 같은 서버에 여러 연결을 할 수 있습니다. 전송하는 알림 수만큼 대상을 처리하기 위해 대상이 필요한 경우 파이프를 통해 바이트를 전송하십시오.


4
신호가 전달되지 않는 방법 (예 : 프로세스가 수신되기 전에 프로세스가 종료되었거나 신호가 병합 됨)을 설명하기 때문에 "신호가 전달되도록 보장됨"이라고 쓰려고 했습니까?
Johnny

2

커널은 차단 된 상태에서 둘 이상이 전달되면 표준 신호를 자유롭게 통합 할 수 있습니다. 반면에 실시간 신호는 유사하게 장애가 없습니다.

에서 신호 (7) 매뉴얼 페이지 :

실시간 신호는 다음과 같이 구별됩니다.

  1. 실시간 신호의 여러 인스턴스가 대기열에있을 수 있습니다. 반대로, 해당 신호가 현재 차단 된 상태에서 표준 신호의 여러 인스턴스가 전달되면 하나의 인스턴스 만 대기합니다.

SIGRTMIN ~ SIGRTMAX 범위의 숫자가있는 신호를 사용해보십시오.


실시간 신호에는 제한이 있지만 상당히 높습니다. 사용자가 보낸 미결 보류 신호의 수가 RLIMIT_SIGPENDING을 초과하면 신호가 삭제됩니다. ulimit -iUbuntu 18.04에서이 값을 63432로 표시합니다.
베인
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.