다중 스레드 Linux 프로세스가 신호를 받으면 어떻게 되나요?

다중 스레드 Linux 프로세스가 신호를 받으면 어떻게 되나요?

Unix(Posix) 프로세스가 신호를 받으면 신호 처리기가 실행됩니다.

다중 스레드 프로세스에서는 어떤 일이 발생합니까? 어떤 스레드가 신호를 수신합니까?

나는 이 문제를 처리하기 위해 신호 API를 확장해야 한다고 생각합니다(즉, 신호 처리기의 스레드를 결정할 수 있어야 함). 그러나 온라인으로 정보를 검색해 보니 Linux 커널 메일링 목록과 다른 포럼에서 1년이 넘는 논쟁이 있었습니다. . 내가 이해하는 한, Linus의 개념은 Posix 표준과 다르며 일부 호환성 계층이 먼저 구축되었지만 이제 Linux는 posix 모델을 따릅니다.

현재 상황은 어떻습니까?

답변1

POSIX의 항목"신호 생성 및 전송"는 "기본: 시스템 인터페이스 일반 정보"에서 언급되었습니다.

프로세스에 대해 생성된 신호는 하나의 스레드에만 전달됩니다. 따라서 여러 스레드가 신호를 수신할 수 있는 경우 하나의 스레드를 선택해야 합니다. 스레드의 선택은 전적으로 구현에 달려 있으며, 가능한 한 가장 광범위하고 일관된 구현을 허용하고 구현이 "가장 쉬운" 스레드에 신호를 전달할 수 있는 자유를 제공합니다(전달 용이성이 스레드마다 다른 경우).

~에서signal(7)Linux 시스템 매뉴얼:

전체 프로세스에 대해 신호가 생성(따라서 일시 중지)될 수 있습니다(예: 다음을 사용하는 경우).kill(2)) 또는 특정 스레드(예: 특정 기계어 명령어의 실행으로 인해 생성된 SIGSEGV 및 SIGFPE와 같은 특정 신호는 특정 스레드에 대한 신호와 마찬가지로 스레드 지향적입니다.pthread_kill(3)). 프로세스 제어 신호는 현재 신호를 차단하지 않는 모든 스레드에 전달될 수 있습니다. 여러 스레드의 신호가 차단되지 않으면 커널은 신호를 전달할 스레드를 선택합니다.

그리고pthreads(7):

스레드에는 서로 다른 대체 신호 스택 설정이 있습니다. 그러나 새 스레드의 백업 신호 스택 설정은 스레드를 생성한 스레드에서 복사되므로 스레드는 처음에 백업 신호 스택을 공유합니다(커널 2.6.16에서 수정됨).

~에서pthreads(3)OpenBSD 시스템 매뉴얼(대체 접근 방식의 예):

신호 처리기는 일반적으로 현재 실행 스레드의 스택에서 실행됩니다.

(현재 다중 프로세서 시스템에서 여러 스레드가 동시에 실행될 때 이를 처리하는 방법을 모르겠습니다.)

POSIX 스레드의 이전 LinuxThread 구현에서는 서로 다른 개별 스레드만 신호의 대상이 되도록 허용했습니다. ~에서pthreads(7)Linux 시스템의 경우:

LinuxThreads는 프로세스 지향 신호 개념을 지원하지 않습니다. 신호는 특정 스레드에만 보낼 수 있습니다.

답변2

더 실용적인 관점을 갖기 위해 받아 들여진 대답을 확장하여 내가 찾은 것여기.

본질은 다음과 같습니다.

신호 처리기는 프로세스별로 처리되지만 신호 마스크는 스레드별로 처리됩니다.

  1. 따라서 신호 처리기를 설치/제거하면(사용하여신호()또는시그액션())모든 스레드에서는 모든 스레드에 영향을 미칩니다.
  2. 프로세스가 신호를 받으면 핸들러는 단일 스레드에서만 실행됩니다. 스레드는 그 중에서 의사 무작위로 선택되며 해당 스레드의 신호 마스크가 이를 수락합니다.내 실험에 따르면 항상 PID가 가장 작은 스레드인 것으로 나타났습니다.*
  3. 스레드로 전송된 신호는 기본 프로세스로 전송된 신호로 간주됩니다. 따라서 한 스레드가 신호를 받으면 다른 스레드가 핸들러를 실행할 가능성이 높습니다. 스레드( s로 식별, 스레드 ID)가 보호된 프로세스( s로 식별) tid로 처리되고 a로 전송된 신호 가 해당 로 전달되는 것을 확인하면 .pidtidpid
  4. 신호 처리기 실행을 위해 주어진 신호 번호는 신호 마스크에 자동으로 마스크됩니다. 이는 스택된 신호 처리기가 신호 버스트에서 실행되는 것을 방지하기 위한 것입니다. 이는 이라는 SA_NODEFER플래그를 통해 변경할 수 있습니다 sigaction(...).
  5. (3)과 (4)의 결과는 신호 버스트의 경우 시스템이 신호 처리 절차를 가장 병렬적인 방식으로 배포할 수 있다는 것입니다.
  6. 그러나 sigaction 을 설정 SA_NODEFER하면항상 동일한 스레드가 신호를 수신하고 스택됩니다..

* 댓글에는 먼저 생성된 스레드일 수도 있다고 나와 있습니다. 둘 다 posix 규격이므로 코드에서 신뢰하지 마세요.

관련 정보