다양한 신호가 전송되는 원인은 무엇입니까?

다양한 신호가 전송되는 원인은 무엇입니까?

때로는 프로세스가 수신할 수 있는 모든 신호에 대해 약간 혼란스러울 때도 있습니다. 내가 이해한 바로는 프로세스에는 기본 핸들러(신호 처리) 각 신호에 대해 호출하지만 자체 핸들러를 제공할 수 있습니다.sigaction().

내 질문은 다음과 같습니다. 각 신호가 전송되는 원인은 무엇입니까? -s에 대한 인수를 통해 실행 중인 프로세스에 수동으로 신호를 보낼 수 있다는 것을 알고 있지만 kill,자연이러한 신호는 어떤 상황에서 전송됩니까? 예를 들어, 언제 SIGINT발송되나요?

또한 어떤 신호를 처리할 수 있는지에 대한 제한이 있나요? SIGSEGV신호를 처리하고 애플리케이션에 제어권을 반환하는 것이 가능합니까 ?

답변1

프로세스 호출 외에도kill(2), 일부신호다양한 상황에서 커널(또는 때로는 프로세스 자체)에 의해 전송됩니다.

  • 터미널 드라이버는 다양한 이벤트에 해당하는 신호를 보냅니다.
    • 키 누름 알림: SIGINT(메인 루프로 돌아가십시오) On Ctrl+ C, SIGQUIT(즉시 종료해주세요) on Ctrl+ \, SIGTSTP(잠깐 멈춰주세요) Ctrl+ Z. 다음 명령을 사용하여 키 입력을 변경할 수 있습니다stty주문하다.
    • SIGTTIN그리고SIGTTOU백그라운드 프로세스가 제어 터미널에서 읽거나 쓰려고 할 때 전송됩니다.
    • SIGWINCH터미널 창의 크기가 변경되었다는 신호를 보냅니다.
    • SIGHUP터미널이 사라졌다는 신호를 보냅니다(역사적으로 모뎀이 사라졌기 때문).시간위로, 이제 일반적으로 터미널 에뮬레이터 창을 닫았기 때문입니다).
  • 일부 프로세서 트랩은 신호를 생성할 수 있습니다. 세부 사항은 아키텍처와 시스템에 따라 다릅니다. 다음은 일반적인 예입니다.
    • SIGBUS메모리에 대한 정렬되지 않은 액세스의 경우;
    • SIGSEGV매핑되지 않은 페이지에 액세스하는 데 사용됩니다.
    • SIGILL잘못된 명령어(잘못된 opcode)
    • SIGFPE매개변수가 잘못된 부동 소수점 명령의 경우(예 sqrt(-1): )
  • 많은 신호는 특정 시스템 이벤트가 발생했음을 대상 프로세스에 알립니다.
    • SIGALRM설정된 타이머가 만료되었음을 프로세스에 알립니다. 타이머는 다음과 같이 설정할 수 있습니다.alarm,setitimer다른 사람.
    • SIGCHLD하위 프로세스 중 하나가 종료되었음을 프로세스에 알립니다.
    • SIGPIPEfoo | bar읽기 측이 닫혀 있는 동안 프로세스가 파이프에 쓰기를 시도할 때 생성됩니다(실행 하고 bar종료 하면 foo에 의해 종료된다는 개념입니다 SIGPIPE).
    • SIGPOLL(라고도 함 SIGIO) 폴링 가능한 이벤트가 발생했음을 프로세스에 알립니다. POSIX는 다음을 통해 등록된 폴링 가능한 이벤트를 지정합니다.I_SETSIG ioctl. 많은 시스템에서는 다음을 통해 모든 파일 설명자에서 폴링 가능한 이벤트를 허용합니다.O_ASYNC fcntl배너. 관련 신호는SIGURG, 장치에 긴급 데이터를 알리는 (등록하여I_SETSIG ioctl) 또는소켓.
    • 일부 시스템에서는SIGPWR모든 프로세스로 전송될 때정전이 임박했음을 나타냅니다.

이 목록은 완전한 것이 아닙니다. 표준 신호는 다음과 같이 정의됩니다.signal.h.

대부분의 신호는 애플리케이션에 의해 포착 및 처리(또는 무시)될 수 있습니다. 캡처할 수 없는 유일한 휴대용 신호는 2개였습니다.SIGKILL(그냥 죽어) 그리고STOP(실행을 중지합니다).

SIGSEGV(세그멘테이션 오류) 그리고 그의 사촌SIGBUS(버스 오류) 잡힐 수도 있지만, 자신이 하고 있는 일을 실제로 알지 않는 한 나쁜 생각입니다. 이를 캡처하기 위한 일반적인 응용 프로그램은 스택 추적이나 기타 디버깅 정보를 인쇄하는 것입니다. 좀 더 발전된 애플리케이션은 일종의 프로세스 내 메모리 관리를 구현하거나 가상 머신 엔진에서 잘못된 명령을 찾아내는 것입니다.

마지막으로 신호가 아닌 것에 대해 언급하겠습니다. 터미널에서 입력을 읽는 프로그램의 줄 시작 부분에서 Ctrl+를 누르면 D프로그램에 입력 파일의 끝에 도달했음을 알립니다. 이는 신호가 아닙니다. 입력/출력 API를 통해 전송됩니다. Like Ctrl+ C및 Friends를 사용하여 버튼을 구성할 수 있습니다 stty.

답변2

먼저 두 번째 질문에 대답하십시오. 애플리케이션에서는 포착할 수 없지만 다른 모든 신호는 포착할 수 있습니다 SIGSTOP. 이 속성은 디버깅에 유용합니다. 예를 들어 올바른 라이브러리 지원을 사용하면 스택 추적을 수신하고 생성하여 표시할 수 있습니다. 세그폴트가 발생한 위치.SIGKILLSIGSEGVSIGSEGV

man 7 signalLinux 명령줄에 입력하면 각 신호의 기능(Linux의 경우)에 대한 공식적인 설명을 얻을 수 있습니다.http://linux.die.net/man/7/signal동일한 정보가 있지만 테이블을 읽기가 더 어렵습니다.

그러나 신호에 대한 경험이 없으면 간단한 설명만으로 신호가 실제로 어떻게 작동하는지 이해하기 어렵습니다. 이에 대한 설명은 다음과 같습니다.

키보드에서 트리거됨

  • SIGINT를 쳤을 때 발생합니다 CTRL+C.
  • SIGQUIT에 의해 트리거되고 CTRL+\코어를 덤프합니다.
  • SIGTSTP을 클릭하면 프로그램이 일시 중지됩니다 CTRL+Z. 와는 달리 , 프로그램이 중단되기 전에 터미널을 안전한 상태로 재설정할 수 있는 기회를 SIGSTOP제공하는 catchable입니다 .vi

터미널 상호 작용

  • SIGHUP("hangup")은 프로그램이 실행되는 동안 xterm이 닫힐 때(또는 터미널에서 연결이 끊어질 때) 발생합니다.
  • SIGTTINSIGTTOU프로그램이 백그라운드에서 실행되는 동안 터미널에서 읽거나 쓰려고 하면 프로그램을 중지합니다. 이런 일이 발생 하려면 SIGTTOU프로그램이 /dev/tty기본 stdout뿐만 아니라 에 작성해야 한다고 생각합니다.

CPU 예외 트리거

이는 프로그램이 뭔가 잘못된 작업을 시도하고 있음을 의미합니다.

  • SIGILL불법적이거나 알 수 없는 프로세서 명령을 나타냅니다. 예를 들어, 프로세서 I/O 포트에 직접 액세스하려고 하면 이런 일이 발생할 수 있습니다.
  • SIGFPE프로그램이 0으로 나누려고 시도했을 가능성이 높은 하드웨어 수학 오류를 나타냅니다.
  • SIGSEGV프로그램이 매핑되지 않은 메모리 영역에 액세스하려고 시도하고 있음을 의미합니다.
  • SIGBUS이는 프로그램이 다른 방식으로 메모리에 잘못 액세스했음을 의미합니다. 이 요약에서는 자세히 설명하지 않겠습니다.

프로세스 상호작용

  • SIGPIPE파이프 판독기가 파이프 끝을 닫은 후 파이프에 쓰려고 하면 이런 일이 발생합니다. 바라보다 man 7 pipe.
  • SIGCHLDSIGSTOP이는 생성한 하위 프로세스가 종료되거나 중단될 때 발생합니다(또는 유사한 방법을 통해 ).

자체 신호 전달에 유용함

  • SIGABRT일반적으로 abort()이 함수를 호출하는 프로그램으로 인해 발생하며 기본적으로 코어 덤프가 발생합니다. 일종의 "패닉 버튼"과 같습니다.
  • SIGALRM이는 커널이 지정된 시간(초) 후에 프로그램에 전달하도록 alarm()하는 시스템 호출 로 인해 발생합니다 . 및 을 SIGALRM참조하십시오 .man 2 alarmman 2 sleep
  • SIGUSR1그리고 SIGUSR2프로그램이 원하는 방식으로 사용하십시오. 프로세스 간 신호를 보내는 데 유용합니다.

관리자가 보냈습니다

이러한 신호 는 일반적 으로 명령 프롬프트에서 전송됩니다 kill.fgbgSIGCONT

  • SIGKILL멈출 수 없는 신호 입니다 SIGSTOP. 첫 번째는 항상 프로세스를 즉시 종료하고 두 번째는 프로세스를 일시 중단합니다.
  • SIGCONT일시 중지된 프로세스를 재개합니다.
  • SIGTERM예, 캡처 가능한 버전입니다 SIGKILL.

답변3

이는 다음을 포함하여 이미 제공된 다른 답변에 추가되거나 추가됩니다.

  1. 킬 신호 목록 [중복]_
  2. 다양한 신호가 전송되는 원인은 무엇입니까?

대부분의 신호에 대한 자세한 설명은 Wikipedia를 참조하세요.https://en.wikipedia.org/wiki/Signal_(IPC)

가장 일반적인 신호 중 하나는 SIGINT프로세스가 실행되는 동안 +를 INT눌러 전송되는 프로그램 인터럽트 신호입니다.CtrlC

~에서위키피디아 기사이상:

SIGINT

"신호 중단"
SIGINT이 신호는 사용자가 프로세스를 중단하기를 원할 때 프로세스를 제어하는 ​​터미널에 의해 프로세스로 전송됩니다. 이는 일반적 Ctrl으로 +를 눌러 시작되지만 일부 시스템에서는 C"삭제" 문자나 키를 사용할 수 있습니다. [12]"break"

실행 중인 프로세스에 수동으로 신호를 보내는 방법

[실행 중인 프로세스에] 다양한 신호가 전송되는 원인은 무엇입니까?

신호가 전송되도록 하는 다른 프로그램이나 키 입력 외에도당신은 그렇습니다!

달리 kill -l거나kill --list실행 중인 프로세스에 보낼 수 있는 모든 신호 나열.

실행 및 출력 예시:

$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX    

예를 들어 "경고" 신호(예 SIGALRM: ALRM또는 신호 번호 14)를 보내려면 다음 중 하나를 수행할 수 있습니다.

kill -SIGALRM <pid>
kill -ALRM <pid>
kill -14 <pid>

killpid에 경고 신호를 보내는 명령 예 123456:

kill -SIGALRM 123456
kill -ALRM 123456
kill -14 123456

다음 내용을 읽어보세요 man kill(강조 추가):

설명하다

기본 신호 kill 는 입니다 TERM. 사용 가능한 신호를 사용 -l하거나 -L나열하십시오. 특히 유용한 신호로는 HUP, INT, KILL, 및 STOP가 있습니다 . CONT0-9대체 신호는 , -SIGKILL또는 3가지 방법으로 지정할 수 있습니다 -KILL. 음수 PID 값은 전체 프로세스 그룹을 선택하는 데 사용될 수 있습니다. ps명령 출력의 PGID 열을 참조하세요. PID -1는 특별합니다. 종료 프로세스 자체와 init를 제외한 모든 프로세스를 나타냅니다.

도착하다관심 있는 프로세스 ID(pid)를 찾으세요., 다음을 실행하세요:

ps aux | grep "some program name string or regular expression to search for"

출력 라인에서 가장 왼쪽의 신호 번호를 찾으십시오. 왼쪽에서 두 번째 열은 PID(프로세스 ID) 번호입니다.

프로그램에서 신호를 잡는 방법

1. 배쉬에서

"트랩", 또는 사용자 지정 신호를 포착하여 그에 따라 조치를 취합니다.세게 때리다SIGALRM프로그램에서는 다음을 수행할 수 있습니다( 신호를 포착합니다 ).

trap <any_comand_to_run_when_signal_is_received> SIGALRM

다음은 사용자 정의 bash 프로그램에서 Ctrl+ C"인터럽트"( SIGINT, INT또는 세마포어) 신호를 포착하는 데 사용하는 일반적인 트랩입니다.2

# Trap the Ctrl + C SIGINT signal from this point onward in the bash program so
# that whenever the user presses Ctrl + C, this program prints `Ctrl + C` and
# then exits with exit code 2 (change that to any exit code you'd like to
# return when Ctrl + C is pressed!).
trap 'printf "%s\n" " Ctrl + C"; exit 2' SIGINT

바라보다:서버 결함: Bash 루핑 - 명령에서 Control-C를 누를 때 루핑을 어떻게 중지합니까?.

2. C와 C++에서

Linux에서 C 또는 C++로 주어진 신호를 포착하고 이에 대해 작업하려면 sigaction()(바람직하게는) 또는 signal()(별로 좋지는 않지만 C 표준의 일부)을 사용할 수 있습니다. 자세한 사용 예와 함께 이에 대한 포괄적인 답변을 참조하세요.스택 오버플로: sigaction과 signal의 차이점은 무엇입니까?

Bash에서 kill신호 보내기(통과) 및 잡기(통과)의 예trap

다음 프로그램에서 trap명령(신호 수신 및 이에 대한 작동) 및 kill명령(프로세스에 신호 보내기)을 검색합니다.

  1. 이 bash 지네 게임을 보세요:
    1. 우분투에 물어보세요: 명령줄 스네이크 게임?
    2. eRCAGuy_hello_world저장소는 여기에 있습니다:지네게임.sh

관련 정보