Unix 시스템에서 시그널(Signal) 함수는 프로세스 간에 비동기적인 이벤트를 처리하는 데 사용되는 다양한 함수들을 포함합니다. 이 함수들은 시그널을 설정, 변경, 확인, 블록하는 데 도움을 주며, 시그널이 발생했을 때의 동작을 제어합니다.
주요 시그널 관련 함수
1. `signal()`
- 기능: 시그널에 대한 핸들러를 설정하거나 기본 동작으로 복원합니다.
- 형식:
void (*signal(int sig, void (*func)(int)))(int); |
- 매개변수:
- `sig`: 설정할 시그널의 번호 (예: `SIGINT`, `SIGTERM` 등).
- `func`: 시그널이 발생했을 때 호출될 핸들러 함수의 포인터. `SIG_IGN`으로 설정하면 시그널을 무시하고, `SIG_DFL`로 설정하면 기본 동작으로 복원합니다.
- 반환값: 이전의 시그널 핸들러 함수 포인터를 반환합니다. 오류 발생 시 `SIG_ERR`를 반환합니다.
예제:
#include #include #include void signal_handler(int signum) { printf("Caught signal %d\n", signum); exit(1); } int main() { // SIGINT 시그널에 대한 핸들러 설정 if (signal(SIGINT, signal_handler) == SIG_ERR) { perror("signal"); exit(1); } // 무한 루프 while (1) { printf("Program running...\n"); sleep(1); } return 0; } |
2. `sigaction()`
- 기능: 시그널에 대한 보다 세밀한 제어를 제공합니다. 시그널 핸들러의 동작 방식을 설정할 수 있습니다.
- 형식:
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); |
- 매개변수:
- `signum`: 설정할 시그널 번호.
- `act`: 새로운 시그널 동작을 정의하는 `struct sigaction` 구조체의 포인터.
- `oldact`: 이전 시그널 동작을 저장할 `struct sigaction` 구조체의 포인터. 이 매개변수는 `NULL`일 수 있습니다.
- 반환값: 성공 시 0을 반환하며, 실패 시 -1을 반환하고 `errno`를 설정합니다.
`struct sigaction`:
struct sigaction { void (*sa_handler)(int); // 시그널 핸들러 함수 포인터 void (*sa_sigaction)(int, siginfo_t *, void *); // 대체 핸들러 함수 포인터 (sigaction() 호출 시만 사용) sigset_t sa_mask; // 시그널 마스크, 핸들러 실행 중 블록할 시그널 집합 int sa_flags; // 동작 플래그 void (*sa_restorer)(void); // 복원 함수, 현재는 사용되지 않음 }; |
예제:
#include #include #include #include void signal_handler(int signum) { printf("Caught signal %d\n", signum); exit(1); } int main() { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGINT, &sa, NULL) == -1) { perror("sigaction"); exit(1); } // 무한 루프 while (1) { printf("Program running...\n"); sleep(1); } return 0; } |
3. `sigemptyset()`, `sigfillset()`, `sigaddset()`, `sigdelset()`
- 기능: 시그널 집합을 초기화하고 수정하는 함수들입니다.
- 형식:
- `sigemptyset(sigset_t *set)`: 시그널 집합을 빈 집합으로 초기화합니다.
- `sigfillset(sigset_t *set)`: 시그널 집합을 모든 시그널을 포함하는 집합으로 초기화합니다.
- `sigaddset(sigset_t *set, int signum)`: 시그널 집합에 시그널을 추가합니다.
- `sigdelset(sigset_t *set, int signum)`: 시그널 집합에서 시그널을 제거합니다.
예제:
#include #include #include int main() { sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGINT); // 현재 시그널 마스크를 시그널 집합으로 설정 if (sigprocmask(SIG_SETMASK, &sigset, NULL) == -1) { perror("sigprocmask"); exit(1); } // 무한 루프 while (1) { printf("Program running, SIGINT blocked...\n"); sleep(1); } return 0; } |
4. `sigprocmask()`
- 기능: 현재 프로세스의 시그널 마스크를 설정하거나 얻습니다.
- 형식:
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); |
- 매개변수:
- `how`: 시그널 마스크를 변경하는 방법을 지정. `SIG_BLOCK`, `SIG_UNBLOCK`, `SIG_SETMASK` 중 하나.
- `set`: 새 시그널 마스크를 설정할 시그널 집합의 포인터.
- `oldset`: 이전 시그널 마스크를 저장할 `sigset_t` 구조체의 포인터. 이 매개변수는 `NULL`일 수 있습니다.
- 반환값: 성공 시 0을 반환하며, 실패 시 -1을 반환하고 `errno`를 설정합니다.
예제:
#include #include #include int main() { sigset_t newmask, oldmask; sigemptyset(&newmask); sigaddset(&newmask, SIGINT); // SIGINT 시그널을 블록 if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) == -1) { perror("sigprocmask"); exit(1); } // 무한 루프 while (1) { printf("Program running, SIGINT blocked...\n"); sleep(1); } return 0; } |
5. `sigpending()`
- 기능: 현재 프로세스에 대해 대기 중인 시그널 집합을 반환합니다.
- 형식:
int sigpending(sigset_t *set); |
- 매개변수:
- `set`: 대기 중인 시그널을 저장할 `sigset_t` 구조체의 포인터.
- 반환값: 성공 시 0을 반환하며, 실패 시 -1을 반환하고 `errno`를 설정합니다.
예제:
#include #include #include int main() { sigset_t pending; sigemptyset(&pending); // SIGINT 시그널을 블록 sigaddset(&pending, SIGINT); if (sigprocmask(SIG_BLOCK, &pending, NULL) == -1) { perror("sigprocmask"); exit(1); } // 대기 중인 시그널 확인 if (sigpending(&pending) == -1) { perror("sigpending"); exit(1); } if (sigismember(&pending, SIGINT)) { printf("SIGINT is pending\n"); } return 0; } |
요약
- 시그널은 비동기적 이벤트 알림 메커니즘입니다.
- 시그널 함수는 시그널을 처리하고 제어하는 데 사용됩니다.
- `signal()`: 간단한 시그널 핸들러 설정.
- `sigaction()`: 세밀한 시그널 핸들러 제어.
- `sigemptyset()`, `sigfillset()`, `sigaddset()`, `sigdelset()`: 시그널 집합 조작.
- `sigprocmask()`: 시그널 마스크 설정 및 확인.
- `sigpending()`: 대기 중인 시그널 확인.
이러한 함수들은 프로세스의 시그널 처리 및 제어를 효율적으로 수행할 수 있게 해줍니다.
'Unix' 카테고리의 다른 글
유닉스 시스템. Bourne Shell(보른 쉘, `sh`) (2) | 2024.09.05 |
---|---|
유닉스(Unix) 시스템. Bourne/C/Korn/Bourne Again/Z/Dash (1) | 2024.09.04 |
Unix에서 시그널(Signal) (0) | 2024.08.31 |
[Unix] 라이브러리 함수와 시스템 콜 비교분석! (1) | 2024.08.30 |
Unix 환경에서 "라이브러리 함수(Library Function) (0) | 2024.08.29 |