에듀테크 프로젝트 대시보드
인터럽트 (Interrupt)
CPU는 한 번에 한 가지 일만 한다. 그런데 키보드 입력, 타이머, 디스크 전송 완료, 네트워크 패킷 도착처럼
언제 일어날지 모르는 사건이 계속 생긴다. 방법은 두 가지다. 하나는 폴링(polling) —
CPU가 "키 눌렸어? 디스크 끝났어?" 하고 계속 물어보는 것. 사건이 드물면 대부분의 질문이 헛수고다.
다른 하나는 인터럽트 — 장치가 준비되면 IRQ 신호선을 당겨 CPU에게 알린다.
CPU는 하던 명령을 마치고 현재 상태(레지스터·PC)를 스택에 저장한 뒤,
인터럽트 벡터 테이블에서 해당 번호의 ISR(인터럽트 서비스 루틴) 주소를 찾아 점프한다.
처리가 끝나면 iret로 저장했던 상태를 복원하고 아무 일 없었다는 듯 원래 코드로 돌아간다.
아래에서 두 방식을 나란히 돌려 보고, CPU가 실제로 어떻게 문맥을 저장·복원하는지 관찰해 보자.
▶ 시작을 누르면 CPU가 메인 프로그램(유용한 계산)을 실행한다. 아래 장치 버튼을 눌러 사건을 발생시켜 보라. 폴링 모드에서는 CPU가 매 사이클마다 장치 3개를 확인하느라 낭비 사이클이 쌓인다. 인터럽트 모드에서는 사건이 있을 때만 문맥 저장 → ISR → 복원 과정이 끼어든다. 타임라인은 최근 CPU 상태를 사이클 단위로 색칠한 것이다.
CPU는 인터럽트 번호를 인덱스로 써서 이 표에서 ISR의 시작 주소를 읽는다.
x86 실제 모드에서는 0x0000부터 256개 항목(각 4바이트)이, 보호 모드에서는
IDT(인터럽트 서술자 테이블)가 같은 역할을 한다. 위쪽 번호일수록 우선순위가 높은 경우가 많다.
| IRQ / 벡터 | 장치·원인 | ISR 주소 | 하는 일 |
|---|---|---|---|
| 0x00 | 0으로 나누기 (예외) | 0x0010:0x4A20 | 프로세스 종료 / 시그널 |
| IRQ 0 | 시스템 타이머 (PIT) | 0x0010:0x7C00 | 틱 카운트++, 스케줄러 호출 |
| IRQ 1 | 키보드 (PS/2) | 0x0010:0x7E40 | 스캔코드 읽어 버퍼에 넣기 |
| IRQ 6 | 플로피 디스크 | 0x0010:0x8120 | 전송 완료 처리 |
| IRQ 14 | 1차 ATA(하드디스크) | 0x0010:0x8330 | 블록 도착 → 대기 프로세스 깨우기 |
| 0x80 | 소프트웨어 인터럽트 | 0x0010:0x9000 | 시스템 콜 디스패치 |
예외(exception)·트랩(trap)은 CPU 내부에서 동기적으로 발생하고, 하드웨어 인터럽트(IRQ)는 외부 장치에서 비동기로 온다. 둘 다 같은 벡터 테이블 메커니즘으로 처리된다.
# 매 명령이 끝날 때마다 CPU 하드웨어가 자동으로 검사한다 while machine_running(): instr = fetch(PC); execute(instr); PC += 1 if IRQ_line and interrupts_enabled: # IF 플래그가 1일 때만 n = read_irq_number() # PIC/APIC가 알려 줌 push(FLAGS); push(CS); push(PC) # ← 문맥 저장(하드웨어) push(regs) # ← 나머지 레지스터(ISR가 저장) interrupts_enabled = False # 중첩 인터럽트 잠시 차단 handler = IVT[n] # 벡터 테이블에서 주소 조회 jump(handler) # ISR 실행 시작 # ... ISR: 장치 상태 읽기, 최소한의 일만, 큐에 넘기고 끝 ... send_EOI(n) # "처리 끝" 신호를 PIC에 pop(regs) interrupts_enabled = True iret() # PC/CS/FLAGS 복원 → 원래 코드로
bottom half(태스크릿·워크큐)로 미룬다.malloc처럼 락을 잡는 함수를 부르면 데드락 위험이 있다.| 폴링 (Polling) | 인터럽트 (Interrupt) | |
|---|---|---|
| CPU 사용 | 사건이 드물어도 계속 확인 → 낭비 | 사건이 있을 때만 개입 |
| 반응 지연 | 다음 확인 시점까지 대기 (주기에 의존) | 거의 즉시 (하던 명령만 마치면) |
| 구현 | 단순 — 그냥 루프에서 플래그 검사 | 하드웨어(PIC/APIC) + 벡터 테이블 + ISR 필요 |
| 고빈도 이벤트 | 문맥 전환 오버헤드 없음 → 오히려 유리 | 인터럽트 폭주 시 오버헤드 (NAPI가 절충) |
| 전력 | CPU가 잠들지 못함 | 유휴 시 저전력 상태 → 인터럽트로 기상 |
실제 시스템은 섞어 쓴다. 리눅스 네트워크 드라이버의 NAPI는 패킷이 몰리면 인터럽트를 끄고 잠깐 폴링으로 전환해 인터럽트 스톰을 막는다. 마우스·키보드처럼 사건이 드문 장치는 순수 인터럽트가 정답이다.