C++ 신호 처리


신호는 운영 체제가 프로세스에 보내는 인터럽트로, 프로그램을 조기에 종료합니다. UNIX, LINUX, Mac OS X 또는 Windows 시스템에서는 Ctrl+C를 눌러 인터럽트를 생성할 수 있습니다.

일부 신호는 프로그램에서 캡처할 수 없지만, 다음 표에 나열된 신호는 프로그램에서 캡처할 수 있으며 해당 신호에 따라 적절한 조치를 취할 수 있습니다. 이러한 신호는 C++ 헤더 파일 <csignal>에 정의되어 있습니다.

abort 호출과 같은 프로그램의 비정상적인 종료를
Signal
SIGABRT설명합니다.
SIGFPE0으로 나누기 또는 오버플로를 유발하는 연산과 같은 잘못된 산술 연산.
SIGILL불법 지시사항을 감지합니다.
SIGINT대화형 주의 신호가 수신되었습니다.
SIGSEGV메모리에 대한 불법적인 접근입니다.
SIGTERM 프로그램에 종료 요청이 전송되었습니다.

signal() 함수

C++ 신호 처리 라이브러리는 예상치 못한 이벤트를 포착하는 signal 함수를 제공합니다. 다음은 signal() 함수의 구문입니다.

void (*signal (int sig, void (*func)(int)))(int);

이 함수는 두 개의 매개변수를 받습니다. 첫 번째 매개변수는 신호 수를 나타내는 정수이고 두 번째 매개변수는 신호 처리 함수에 대한 포인터입니다.

signal() 함수를 사용하여 SIGINT 신호를 캡처하는 간단한 C++ 프로그램을 작성해 보겠습니다. 프로그램에서 포착하려는 신호가 무엇이든 signal 함수를 사용하여 신호를 등록하고 신호 처리기와 연결해야 합니다. 다음 예를 살펴보십시오.

#include <iostream>
#include <csignal>

using namespace std;

void signalHandler( int signum )
{
    cout << "Interrupt signal (" << signum << ") received.\n";

    // 清理并关闭
    // 终止程序  

   exit(signum);  

}

int main ()
{
    // 注册信号 SIGINT 和信号处理程序
    signal(SIGINT, signalHandler);  

    while(1){
       cout << "Going to sleep...." << endl;
       sleep(1);
    }

    return 0;
}

위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.

Going to sleep....
Going to sleep....
Going to sleep....

이제 Ctrl+C를 눌러 프로그램을 중단하면 프로그램이 신호를 포착하는 것을 볼 수 있습니다. 그러면 프로그램은 다음을 인쇄하고 종료합니다.

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.

raise() 함수

다음 구문을 사용하여 정수 신호 번호를 매개변수로 사용하는 raise() 함수를 사용하여 신호를 생성할 수 있습니다.

int raise (signal sig);

여기서는 sig가 전송됩니다. 신호 수, 이러한 신호에는 SIGINT, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERM, SIGHUP이 포함됩니다. 다음은 raise() 함수를 사용하여 내부적으로 신호를 생성하는 예입니다.

#include <iostream>
#include <csignal>

using namespace std;

void signalHandler( int signum )
{
    cout << "Interrupt signal (" << signum << ") received.\n";

    // 清理并关闭
    // 终止程序 

   exit(signum);  

}

int main ()
{
    int i = 0;
    // 注册信号 SIGINT 和信号处理程序
    signal(SIGINT, signalHandler);  

    while(++i){
       cout << "Going to sleep...." << endl;
       if( i == 3 ){
          raise( SIGINT);
       }
       sleep(1);
    }

    return 0;
}

위 코드를 컴파일하고 실행하면 다음 결과가 생성되고 자동으로 종료됩니다.

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.