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()` 등 다양한 함수가 이를 지원합니다.
'Unix' 카테고리의 다른 글
유닉스(Unix) 시스템. Bourne/C/Korn/Bourne Again/Z/Dash (1) | 2024.09.04 |
---|---|
Unix 시스템에서 시그널(Signal) 함수(비동기적인 이벤트를 처리) (1) | 2024.09.01 |
[Unix] 라이브러리 함수와 시스템 콜 비교분석! (1) | 2024.08.30 |
Unix 환경에서 "라이브러리 함수(Library Function) (0) | 2024.08.29 |
[unix] 시스템 콜(System Call) (1) | 2024.08.28 |