이번 글에서는 Ctrl + C 키를 눌러도 종료되지 않는 C 프로그램을 작성하는 방법을 알아보겠습니다.
일반적으로 Ctrl + C 키는 키보드 인터럽트(keyboard interrupt)를 발생시켜 현재 실행 중인 프로세스를 중단시킵니다. 하지만 시그널(signal) 처리 기법을 활용하면 Ctrl + C가 눌렸을 때 프로세스를 종료하는 대신 특정 메시지를 출력한 뒤 계속 실행하도록 만들 수 있습니다.
Ctrl + C가 눌리면 운영체제는 SIGINT라는 시그널을 프로그램에 전달합니다. C 언어에서는 이러한 시그널을 직접 처리(catch)할 수 있으며, 주요 시그널의 종류와 기능은 다음과 같습니다.
주요 시그널의 종류
| 시그널 | 설명 |
|---|---|
| SIGABRT | 비정상적인 종료(abnormal termination)가 발생했음을 나타냅니다. |
| SIGFPE | 부동 소수점 연산 예외(floating point exception)가 발생했음을 나타냅니다. |
| SIGILL | 잘못된 명령어(invalid instruction)가 감지되었음을 나타냅니다. |
| SIGINT | 프로그램에 전달되는 인터랙티브한 주의 요청(예: Ctrl + C)을 나타냅니다. |
| SIGSEGV | 잘못된 메모리 접근(invalid memory access)이 발생했음을 나타냅니다. |
| SIGTERM | 프로그램에 보내진 종료 요청(termination request)을 나타냅니다. |
이러한 시그널을 처리하기 위해 C 표준 라이브러리의 signal() 함수를 사용합니다. 아래 예제에서는 SIGINT 시그널이 발생할 때마다 핸들러 함수가 호출되도록 등록하고, 무한 루프 안에서 프로그램이 계속 실행되도록 구현했습니다.
예제 코드
#include <stdio.h>
#include <signal.h>
void sigint_handler(int signum) { // SIGINT용 핸들러
// 다음 SIGINT 시그널도 받을 수 있도록 핸들러 재등록
signal(SIGINT, sigint_handler);
printf("Cannot be stopped using Ctrl+C \n");
fflush(stdout);
}
main () {
signal(SIGINT, sigint_handler);
while(1) { // 무한 루프 생성
}
}실행 결과
Cannot be stopped using Ctrl+C Cannot be stopped using Ctrl+C
위 코드를 실행한 상태에서 Ctrl + C를 누르면 프로그램이 종료되지 않고, 대신 "Cannot be stopped using Ctrl+C"라는 메시지가 출력되며 계속 실행됩니다. 여기서 한 가지 주목할 점은 핸들러 함수 내부에서 signal()을 다시 호출한다는 것입니다. 일부 시스템에서는 시그널 핸들러가 한 번 호출된 후 기본 동작(default behavior)으로 초기화되기 때문에, 핸들러를 재등록해야 이후에 발생하는 SIGINT 시그널도 계속 처리할 수 있습니다.