컴퓨터 시스템 8장 시그널
2025. 4. 21. 14:21ㆍ개념 공부
8.1.1 Exception Handling (예외 처리)
예외란?
프로그램의 일반적인 흐름과 다르게, 특별한 이벤트가 발생해서 실행 흐름이 바뀌는 것
- 0으로 나누기 (Divide by zero)
- 메모리 접근 오류
- 타이머 인터럽트
- I/O 완료 알림
핵심 구조: 예외 처리 흐름
예외 발생 → 예외 테이블(주소 찾기) → 예외 핸들러 실행 → 복귀 or 종료
예외가 발생하면 CPU는 Exception Table (예외 테이블)이라는 점프 테이블을 참고해서 해당 예외에 맞는 핸들러 함수를 호출함. 이 과정은 간접 프로시저 호출(indirect procedure call)로 이루어짐.
예외 처리 전체 흐름
- 이벤트 발생
- 예외 번호 k 결정
- Exception Table[k]에서 핸들러 주소 확인
- 해당 핸들러 코드로 점프!
- 핸들러가 예외 처리 수행
- 복귀 or 프로그램 종료
예외 번호 (Exception Number)
- 예외마다 고유한 번호가 있음 (ex. 0번: divide by zero, 14번: page fault)
- 이 번호를 index처럼 사용해서 Exception Table에서 해당 핸들러 주소를 찾음
Exception Table이란?
각 예외 번호에 대해, 해당 예외를 처리할 핸들러 주소를 저장한 테이블
예외 테이블의 시작 주소는 CPU의 특수 레지스터에 저장되어 있음 (ex: x86-64에서는 IDTR)
Exception number k = 14 → Exception Table[14] → page_fault_handler 주소
예외 핸들러는 어떤 일 해?
- CPU는 예외 발생 시 현재 명령 상태(PC, EFLAGS 등)를 커널 스택에 저장
- 핸들러는 커널 모드에서 실행됨
- 다음 중 하나 수행:
- ❶ 현재 명령으로 복귀
- ❷ 다음 명령으로 이동
- ❸ 프로그램 종료
예외 처리 시 스택에 저장되는 정보
- 리턴 주소 (예외 발생 명령 or 다음 명령)
- EFLAGS
- 기타 CPU 상태 정보
8.1.2 예외의 종류 (Classes of Exceptions)
예외는 두 기준으로 분류돼:
- 동기(Synchronous) vs 비동기(Asynchronous)
- 복귀 가능 여부
📋 4가지 클래스
| 종류 | 원인 | 동기/비동기 | 복귀 방식 |
|---|---|---|---|
| Interrupt | I/O 장치가 보낸 외부 신호 | 비동기 | Inext |
| Trap | 의도된 예외 (시스템 호출) | 동기 | Inext |
| Fault | 복구 가능한 에러 | 동기 | Icurr |
| Abort | 복구 불가 에러 | 동기 | 복귀 불가 |
8.2.2 Concurrent Flows (동시적인 흐름)
여러 흐름이 시간상 겹쳐서 실행되면 Concurrent 라고 해.
예시:
- A 프로세스: 1~3초 실행
- B 프로세스: 2~5초 실행
Concurrent vs Parallel
| 용어 | 의미 | 예시 |
|---|---|---|
| Concurrent | 시간상 겹쳐서 실행 | A → B → A → B |
| Parallel | 진짜 동시에 실행 (멀티코어) | A는 CPU1, B는 CPU2 |
8.2.3 Private Address Spaces (프로세스 독립 주소 공간)
- 각 프로세스는 독립된 메모리 공간을 가짐
- 서로의 변수/메모리에 접근 불가
주소 공간 구성:
- 코드, 데이터, 힙, 스택
- 공유 라이브러리
- 시스템 콜 인터페이스
8.3 시스템 콜 에러 처리
시스템 콜은 항상 성공하진 않기 때문에 에러 처리를 꼭 해줘야 해
📌 래퍼 함수 예시:
pid_t Fork(void) {
pid_t pid;
if ((pid = fork()) < 0)
unix_error("Fork error");
return pid;
}
8.4.6 fork와 execve로 프로그램 실행하기
- 명령어 입력 받기
- 파싱하여 명령어/인자 분리
fork()로 자식 생성execve()로 프로그램 실행
백그라운드 실행
- 명령어 끝에
&붙이면wait()하지 않고 다음 입력 받음
Program vs Process
| 용어 | 설명 |
|---|---|
| Program | 정적인 코드/데이터 파일 |
| Process | 실행 중인 프로그램 인스턴스 |
8.5.2 Sending Signals (시그널 보내기)
시그널 보내기 방법
/bin/kill -9 [pid]→ 프로세스 종료kill(getpid(), SIGINT);→ 자기 자신에게 보내기
키보드 입력과 시그널
| 입력 | 시그널 | 동작 |
|---|---|---|
| Ctrl+C | SIGINT | 종료 |
| Ctrl+Z | SIGTSTP | 일시 정지 |
8.5.3 Receiving Signals (시그널 수신)
언제 처리됨?
- 시스템 콜 끝나고 사용자 모드 복귀할 때
- 컨텍스트 스위치 직후
기본 동작
- 종료, 무시, 중단 등
사용자 정의 핸들러
void sigint_handler(int sig) {
printf("Ctrl+C 눌렀네!\n");
exit(0);
}
int main() {
signal(SIGINT, sigint_handler);
while (1) pause();
}
시그널 큐잉 안 됨
- 같은 시그널이 여러 번 와도 한 번만 pending
잘못된 예시
void handler1(int sig) {
waitpid(-1, NULL, 0); // 하나만 수거
sleep(1);
}
정확한 처리
void handler(int sig) {
while (waitpid(-1, NULL, 0) > 0)
; // 반복해서 다 수거
}'개념 공부' 카테고리의 다른 글
| 운영체제 아주 쉬운 세가지 이야기- 1주차 스터디 (1) | 2025.09.02 |
|---|---|
| 컴퓨터 네트워킹 & 소켓 인터페이스 (0) | 2025.05.07 |
| 컴퓨터 시스템 7장-링커(Linking) 1-2 (0) | 2025.04.19 |
| 컴퓨터 시스템 7장-링커(Linking) 1-1 (0) | 2025.04.19 |
| 포인터 (0) | 2025.04.14 |