본문 바로가기
임베디드SW 기초

시스템 프로그래밍(4) - 시그널 관련 시스템 콜

by sw-develop-record 2025. 2. 26.
  • signal(): 시그널 핸들러를 등록합니다.
  • pause(): 시그널을 받을 때까지 프로세스를 일시 중지합니다.
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

// 시그널 핸들러 함수
void signal_handler(int signum) {
    printf("시그널 %d 수신됨\\n", signum);
}

int main() {
    // SIGINT(Ctrl+C) 시그널에 대한 핸들러 등록
    if (signal(SIGINT, signal_handler) == SIG_ERR) {
        perror("시그널 핸들러 등록 실패");
        return 1;
    }
    
    printf("SIGINT(Ctrl+C) 시그널을 기다리는 중...\\n");
    printf("Ctrl+C를 눌러보세요.\\n");
    
    // 시그널이 도착할 때까지 프로세스 일시 중지
    pause();
    
    printf("시그널 처리 후 계속 실행됩니다.\\n");
    
    return 0;
}


  • sigaction(): 시그널 처리 동작을 설정합니다.
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

// 시그널 핸들러 함수
void sigaction_handler(int signum, siginfo_t *info, void *context) {
    printf("시그널 %d 수신됨\\n", signum);
    printf("시그널 발생 프로세스 ID: %d\\n", info->si_pid);
}

int main() {
    struct sigaction sa;
    
    // sigaction 구조체 초기화
    memset(&sa, 0, sizeof(sa));
    
    // 시그널 핸들러 설정
    sa.sa_sigaction = sigaction_handler;
    
    // 추가 정보를 받기 위한 플래그 설정
    sa.sa_flags = SA_SIGINFO;
    
    // SIGUSR1 시그널에 대한 처리 등록
    if (sigaction(SIGUSR1, &sa, NULL) == -1) {
        perror("sigaction 설정 실패");
        return 1;
    }
    
    printf("SIGUSR1 시그널을 기다리는 중... (PID: %d)\\n", getpid());
    printf("다른 터미널에서 'kill -SIGUSR1 %d' 명령을 실행해보세요.\\n", getpid());
    
    // 시그널이 도착할 때까지 프로세스 일시 중지
    pause();
    
    printf("시그널 처리 후 계속 실행됩니다.\\n");
    
    return 0;
}


  • kill(): 프로세스에 시그널을 보냅니다.
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

// 시그널 핸들러
void signal_handler(int signum) {
    printf("자식 프로세스: 시그널 %d 수신됨\\n", signum);
}

int main() {
    pid_t pid = fork();
    
    if (pid < 0) {
        perror("fork 실패");
        return 1;
    } 
    else if (pid == 0) {
        // 자식 프로세스
        
        // SIGUSR1 시그널 핸들러 등록
        signal(SIGUSR1, signal_handler);
        
        printf("자식 프로세스(PID: %d)가 시그널을 기다립니다...\\n", getpid());
        
        // 시그널을 기다리며 일시 정지
        pause();
        
        printf("자식 프로세스가 종료됩니다.\\n");
        exit(0);
    } 
    else {
        // 부모 프로세스
        sleep(1);  // 자식 프로세스가 준비할 시간
        
        printf("부모 프로세스가 자식(PID: %d)에게 SIGUSR1 시그널을 보냅니다.\\n", pid);
        
        // 자식 프로세스에 SIGUSR1 시그널 전송
        if (kill(pid, SIGUSR1) == -1) {
            perror("kill 실패");
            return 1;
        }
        
        // 자식 프로세스가 종료될 때까지 대기
        wait(NULL);
        printf("부모 프로세스: 자식 프로세스 종료됨\\n");
    }
    
    return 0;
}


  • raise(): 현재 프로세스에 시그널을 보냅니다.
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

// 시그널 핸들러
void signal_handler(int signum) {
    printf("시그널 %d 수신됨 (자기 자신이 보낸 시그널)\\n", signum);
}

int main() {
    // SIGUSR1 시그널 핸들러 등록
    if (signal(SIGUSR1, signal_handler) == SIG_ERR) {
        perror("시그널 핸들러 등록 실패");
        return 1;
    }
    
    printf("현재 프로세스(PID: %d)가 자기 자신에게 SIGUSR1 시그널을 보냅니다.\\n", getpid());
    
    // 자기 자신에게 SIGUSR1 시그널 보내기
    if (raise(SIGUSR1) != 0) {
        perror("raise 실패");
        return 1;
    }
    
    printf("시그널 처리 후 계속 실행됩니다.\\n");
    
    return 0;
}