신호가 수신되면 어떤 예외 처리기가 먼저 호출됩니까?

신호가 수신되면 어떤 예외 처리기가 먼저 호출됩니까?

sleep()이 함수를 사용하는 C 프로그램이 있다고 가정해 보겠습니다 .

프로그램이 실행되고 절전 모드로 전환됩니다. 그런 다음 Ctrl+를 입력하여 c프로세스에 신호를 보냅니다.SIGINT

우리는 a를 받은 후 기본 동작이 SIGINT프로세스를 종료하는 것임을 알고 있으며, 잠자는 프로세스가 무시되지 않은 신호를 받을 때마다 sleep 함수가 일찍 반환된다는 것도 알고 있습니다.

Ctrl+ 를 입력하면 c함수 sleep()가 먼저 반환되나요, 아니면 프로세스가 먼저 종료되나요?

답변1

기본 작업은 SIGINT문서( signal(7)여기 OpenBSD에서 가져옴)에 따라 프로세스를 종료하는 것입니다.

These signals are defined in the file <signal.h>:

Name         Default Action       Description
SIGHUP       terminate process    terminal line hangup
SIGINT       terminate process    interrupt program

이론적으로는 종료로 인해 프로세스에 더 많은 코드를 실행할 기회가 주어져서는 안 됩니다. 간단한 리트머스 테스트는 무슨 일이 일어나고 있는지 보여주는 데 도움이 될 수 있습니다(그러나 처리되지 않은 코드 이후에 프로세스의 코드가 실행되지 않았다는 것을 증명하지는 않습니다 SIGINT).

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

void sigint(int sig)
{
    fprintf(stderr, "got INT\n");
}

void warnexit(void)
{
    fprintf(stderr, "atexit\n");
}

int main(void)
{
    atexit(warnexit);
    //signal(SIGINT, sigint);
    fprintf(stderr, "%d\n", getpid());
    sleep(640);
    fprintf(stderr, "ouch!\n");
    return 0;
}

handler 를 주석 처리한 후에는 프로그램을 종료 signal(...)합니다 . 핸들러나 행이 실행 중이 control+c 라는 표시는 없습니다 .atexitouch

$ make sleepint
egcc -O2 -pipe    -o sleepint sleepint.c 
$ ./sleepint
31761
^C
$ 

handler 의 주석 처리를 제거하면 signal(...)나머지 코드에 접근할 수 있습니다.

$ make sleepint
egcc -O2 -pipe    -o sleepint sleepint.c 
$ ./sleepint 
64094
^Cgot INT
ouch!
atexit
$ 

SIGINT그러나 처리는 실제로 매우 복잡하다는 점에 유의하십시오 . 쉘 및 기타 프로세스에는 일반적 SIGINT으로 핸들러가 있으며(그렇지 않으면 쉘이 종료되어 좋지 않을 수 있음) 키를 누르면 control+c포그라운드 프로세스 그룹에 신호가 전송되지 않을 수 있습니다(프로그램은 터미널을 원시 모드로 전환할 수 있음) , 예를 들어 ncurses cbreak()호출을 하면 키가 표시됩니다 ETX.다른 껍질은 다른 일을 합니다.. control+c​또한 이 플래그를 사용하여 다양한 시스템 호출의 작동 방식을 변경할 sigaction(2)수 있습니다.SA_RESTART

관련 정보