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
라는 표시는 없습니다 .atexit
ouch
$ 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