본문 바로가기
Unix

Unix에서 시그널(Signal)

by mdesign 2024. 8. 31.

Unix에서 시그널(Signal)은 프로세스 간에 비동기적인 통신을 제공하는 메커니즘입니다. 시그널은 특정 사건이나 조건이 발생했음을 프로세스에 알리기 위해 운영체제에서 사용하는 소프트웨어 인터럽트입니다. 이 기능은 프로세스가 이벤트에 응답하거나 시스템의 상태를 제어할 수 있게 합니다.


 시그널의 주요 개념

1. 비동기성:

   - 시그널은 비동기적으로 발생합니다. 즉, 시그널이 발생한 시점은 예측할 수 없으며, 프로세스가 현재 수행 중인 작업과는 독립적으로 시그널이 전달될 수 있습니다.


2. 처리 및 무시:

   - 프로세스는 시그널을 처리하거나 무시할 수 있습니다. 시그널을 처리하는 방법으로는 시그널 핸들러를 설정하여 시그널이 발생했을 때 호출될 함수를 지정할 수 있습니다. 시그널을 무시하면 기본적인 동작(예: 종료, 중지 등)을 하지 않고 넘어갑니다.


3. 기본 동작:

   - 각 시그널에는 기본 동작이 정의되어 있습니다. 예를 들어, `SIGINT` 시그널은 기본적으로 프로그램을 종료시키며, `SIGSTOP`은 프로세스를 일시 중지합니다.


4. 핸들러 설정:

   - 시그널 핸들러를 설정하여 시그널이 발생했을 때 특정 작업을 수행하도록 할 수 있습니다. 핸들러는 시그널이 발생할 때 실행될 함수입니다.


5. 시그널 종류:

   - 시그널에는 다양한 종류가 있으며, 각 시그널은 특정한 사건이나 조건을 나타냅니다.


 주요 시그널 종류

시그널 설   명                                                       기본 동작
SIGINT 인터럽트 시그널, 보통 Ctrl+C로 발생      프로세스 종료
SIGTERM 종료 시그널, 프로세스에 종료를 요청  프로세스 종료
SIGKILL  강제 종료 시그널, 프로세스를 강제로 종료  프로세스 종료
SIGSTOP 일시 중지 시그널, 프로세스를 일시 중지  프로세스 일시 중지
SIGCONT  계속 시그널, 일시 중지된 프로세스를 다시 실행 프로세스 실행 재개
SIGQUIT 종료 및 코어 덤프 시그널, 보통 Ctrl+\로 발생   프로세스 종료 및 코어 덤프 생성
SIGUSR1 사용자 정의 시그널 1, 사용자 정의 목적에 사용      기본 동작 없음
SIGUSR2  사용자 정의 시그널 2, 사용자 정의 목적에 사용    기본 동작 없음
SIGSEGV 세그멘테이션 폴트, 잘못된 메모리 접근 시 발생 프로세스 종료 및 코어 덤프 생성
SIGPIPE 파이프 쓰기 오류, 파이프가 읽히지 않았을 때 쓰기 작업 시 발생 프로세스 종료 |

 

 시그널 처리 방법

1. 기본 동작:


   - 기본적으로 각 시그널에는 시스템에서 정의한 기본 동작이 있습니다. 예를 들어, `SIGINT`는 프로그램을 종료시키고, `SIGSTOP`은 프로세스를 일시 중지합니다.


2. 시그널 핸들러 설정:

   - `signal()` 또는 `sigaction()` 함수를 사용하여 시그널에 대한 핸들러를 설정할 수 있습니다. 핸들러 함수는 시그널이 발생했을 때 실행될 코드를 포함합니다.

  예제: 시그널 핸들러 설정

   #include 
   #include 
   #include 

   // 시그널 핸들러 함수
   void signal_handler(int signum) {
       printf("Caught signal %d\n", signum);
       // 필요한 처리를 추가
   }

   int main() {
       // SIGINT 시그널에 대한 핸들러 설정
       if (signal(SIGINT, signal_handler) == SIG_ERR) {
           printf("Unable to catch SIGINT\n");
           exit(1);
       }

       // 무한 루프
       while (1) {
           printf("Program running...\n");
           sleep(1);
       }

       return 0;
   }


   위 코드에서 `signal_handler` 함수는 `SIGINT` 시그널이 발생했을 때 호출됩니다. 이 예제는 Ctrl+C를 눌러 프로그램을 중단할 때 커스텀 메시지를 출력합니다.


3. 시그널 무시:

   - `signal()` 함수를 사용하여 특정 시그널을 무시할 수도 있습니다.

   예제: 시그널 무시

   #include 
   #include 
   #include 

   int main() {
       // SIGINT 시그널 무시
       if (signal(SIGINT, SIG_IGN) == SIG_ERR) {
           printf("Unable to ignore SIGINT\n");
           exit(1);
       }

       // 무한 루프
       while (1) {
           printf("Program running, SIGINT ignored...\n");
           sleep(1);
       }

       return 0;
   }


  이 예제는 `SIGINT` 시그널을 무시하므로, Ctrl+C를 눌러도 프로그램이 종료되지 않습니다.


 요약

- 시그널은 Unix 시스템에서 프로세스 간 비동기적 통신을 제공하며, 특정 사건이나 상태를 알리기 위한 메커니즘입니다.
- 시그널은 프로세스에 전달되어 특정 동작을 유도하거나, 시그널 핸들러를 통해 사용자 정의 작업을 수행할 수 있습니다.
- 기본 동작을 변경하거나 핸들러를 설정하여 시그널에 대응할 수 있으며, `signal()`, `sigaction()` 등 다양한 함수가 이를 지원합니다.