신호를 무시(분실)할 수 있나요?

신호를 무시(분실)할 수 있나요?

신호(특히 SIGUSR1/SIGUSR2/SIGSTOP)를 통해 작업자와 통신하는 애플리케이션이 있습니다.

무슨 일이 일어나더라도 모든 신호가 핸들러에 의해 전달되고 처리될 것이라고 믿을 수 있습니까?

애플리케이션이 처리할 수 있는 것보다 더 빠르게 신호가 전송되면(예: 현재 높은 호스트 로드로 인해) 어떻게 되나요?

답변1

"너무 많은 신호" 문제 외에도 명시적으로 신호를 무시하는 것도 가능합니다. ~에서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.

차단 및 무시된 신호 세트는 하위 프로세스에 상속되므로 애플리케이션의 상위 프로세스는 이러한 신호 중 하나를 무시하거나 차단할 수 있습니다.

프로세스가 이전 신호 처리를 완료하기 전에 여러 신호가 전달되면 어떻게 되나요? 이는 운영 체제에 따라 다릅니다. 위에 링크된 맨페이지에서는 signal(2)이에 대해 설명합니다.

  • System V는 신호 처리를 기본값으로 재설정합니다. 더 나쁜 것은 여러 신호를 빠르게 전달하면 재귀(?) 호출이 발생한다는 것입니다.
  • BSD는 핸들러가 완료될 때까지 자동으로 신호를 차단합니다.
  • Linux에서는 GNU에 설정된 컴파일 플래그에 따라 다르지만 libcBSD 동작이 예상됩니다.

답변2

당신이 보내는 모든 신호가 전달될 것이라고 믿을 수는 없습니다. 예를 들어,Linux 커널은 SIGCHLD를 "병합"합니다.프로세스가 하위 프로세스를 종료하는 SIGCHLD를 처리하는 데 오랜 시간이 걸리는 경우.

질문의 다른 부분에 대답하자면, 너무 짧은 시간에 많은 다른 신호가 도착하면 신호가 커널 내부에 "대기"될 수 있습니다.

멤버를 사용하여 sigaction()신호 처리기를 설정하고 멤버의 매개변수를 신중하게 설정해야 합니다. 나는 이것이 적어도 모든 "비동기" 신호를 차단한다는 것을 의미한다고 생각합니다. Linux 매뉴얼 페이지에 따르면 처리 중인 신호도 마스킹합니다. 멤버를 SA_SIGINFO로 설정해야 할 것 같은데 왜 이런 미신이 있는지 기억이 나지 않습니다. 나는 이것이 당신의 프로세스가 경쟁 조건 없이 설정된 상태를 유지하고 대부분의 다른 신호에 의해 중단되지 않는 신호 처리기를 얻을 수 있다고 믿습니다.sa_sigactionsiginfo_tsa_masksiginfo_tsigaction()sa_flags

신호 처리 기능을 매우 주의 깊게 작성하십시오. 기본적으로 신호가 포착되었음을 나타내기 위해 전역 변수를 설정하고 프로세스의 나머지 부분이 해당 신호에 필요한 것을 처리하도록 하십시오. 이렇게 하면 가능한 가장 짧은 시간 동안 신호가 차단됩니다.

또한 신호 처리 코드를 매우 철저하게 테스트해야 합니다. 이를 소규모 테스트 프로세스에 적용하고 2~3개의 전용 신호 전송기에서 가능한 한 많은 SIGUSR1 및 SIGUSR2 신호를 보냅니다. 코드가 SIGUSR1 및 SIGUSR2를 빠르고 정확하게 처리할 수 있다는 확신이 들면 다른 신호를 혼합할 수 있습니다. 어려운 디버깅에 대비하세요.

signalfd()Linux를 사용하고 Linux만 사용하는 경우 이를 사용 하여 파일 설명자를 생성 select()하거나 이러한 신호를 수신하기 위해 폴링하는 것을 고려할 수 있습니다 . 를 사용하면 signalfd()디버깅이 더 쉬워질 수 있습니다.

답변3

kill프로세스가 성공적으로 호출되면 대상이 신호를 수신한다는 의미에서 신호 전달이 보장됩니다 . 이는 비동기식입니다. 발신자는 신호가 언제 수신되거나 처리되는지 알 수 없습니다. 그러나 이것이 신호 전달을 보장하지는 않습니다. 신호가 처리되기 전에 대상이 죽을 수 있습니다. 대상이 신호를 보낼 때 신호를 무시하면 신호는 아무런 효과가 없습니다. 신호를 처리하기 전에 대상이 동일한 신호 번호의 여러 인스턴스를 수신하면 신호가 병합될 수 있으며 종종 병합됩니다. 동일한 신호를 프로세스에 두 번 보내는 경우 프로세스가 신호를 한 번 또는 두 번 수신하는지 알 수 있는 방법이 없습니다. . 신호는 주로 프로세스를 종료하거나 프로세스에 주의를 기울이도록 설계되었으며 통신 자체를 위해 설계되지 않았습니다.

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

답변4

차단하는 동안 여러 표준 신호가 전달되면 커널은 표준 신호를 자유롭게 병합할 수 있습니다. 반면에 실시간 신호에는 동일한 단점이 발생하지 않습니다.

~에서signal(7) 매뉴얼 페이지:

실시간 신호에는 다음과 같은 특징이 있습니다.

  1. 실시간 신호의 여러 인스턴스가 대기열에 포함될 수 있습니다. 대조적으로, 해당 신호가 현재 차단되어 있는 동안 표준 신호의 여러 인스턴스가 전달되면 하나의 인스턴스만 대기열에 추가됩니다.

SIGRTMIN에서 SIGRTMAX 범위의 숫자가 포함된 신호를 사용해 보세요.

관련 정보