본문 바로가기
Programming

Termination Signal Control - SIGINT, SIGTERM 에 대한 제어

by leanu 2008. 10. 6.

Introduction
---------------------------------------------------------------------------------------------
  Unix 나 프로그램을 종료하게 되는 경우 Ctrl-C 를 이용하게 된다. 만약 프로그램에서 파일에 무언가를 쓰고 있는 중간에 갑작스런 종료를 하게 된다면, 파일에 손상이 생겨서 다음번에 사용할 수 없을수도 있다. 그렇다면 그런 신호에 대한 뒷처리(예를 들면, 파일을 종료하거나...)를 하고 싶을때는 어떻게 해야 할까? 바로 Signal 처리에 답이 있다.

  p.s "kill -9" 같이 강제 종료하는 것에 대한 signal처리는 운영체제 상으로 금지되어 있다.( 즉 신호감지를 못한다.) 왜냐하면 이것마저도 제어권을 프로그램에게 넘겨버린다면, 한번 실행되면 종료할 수 없는 프로그램을  만들수도 있기 때문이다. 우리가 처리하고자 하는 신호는 SIGTERM (기본 소프트웨어 종료 신호) SIGINT (Ctrl+C 시 발생하는 신호) 이렇게 두가지 이다. 따라서 이번에 다루는 내용은 완전한 transaction 처리라고는 할 수 없다.


Source & How to use it
---------------------------------------------------------------------------------------------

   우선 소스를 보자

/// @file TerminationMananager.h
/// @author Dohyun Yun
/// @brief A Class to manage termination control.

#include <iostream>
#include <signal.h>

class TerminationManager
{
public:

    static int catchTerminationSignal(void handler(int))
    {
        struct sigaction act;
        act.sa_handler = handler;
        sigemptyset(&act.sa_mask);
        act.sa_flags = 0;

        if (sigaction(SIGINT, &act, 0) < 0)
        {
            std::cerr << "error: Cannot register SIGTERM" << std::endl;
            return -1;
        }

        if (sigaction(SIGTERM, &act, 0) < 0)
        {
            std::cerr << "error: Cannot set SIGTERM" << std::endl;
            return -1;
        }

        return 0;
    }

};
#include <TerminationManager.h>

static void handler(int signo)
{
    std::cerr << "Warning : Signal occurs (" << signo << ")" << std::endl;
}

int main()
{
    TerminationManager::ccatchTerminationSignal(handler);
    while(1){};
    return 0;
}

사용법은 간단하다. 맨 아래 main 함수를 보면 함수의 copy본을 TerminationManager에 등록하게 되는데, sigaction 에서 정의한 SIGINT 와 SIGTERM을 부른 경우 handler함수를 호출하게 되는 형식으로 진행된다. 이때 유의할 점은 클래스들의 소멸자는 당근 안불려진다는 사실이다. (당연하다. 갑자기 종료인데..)

댓글