인터럽트: 기다리며 묻지 않아도 사건을 알 수 있는 방식
CPU가 장치 작업이 끝났는지 계속 물으면 다른 계산에 사용할 시간을 낭비할 수 있다. 인터럽트는 장치 완료나 타이머 같은 사건이 발생했을 때 CPU의 실행 흐름을 정해진 처리 코드로 잠시 바꾸는 메커니즘이다. 사건을 확인하고 필요한 조치를 수행한 뒤 원래 작업을 이어 가거나 운영체제의 판단에 따라 다른 작업을 실행할 수 있다.
사건을 처리하는 인터럽트 진입과 다른 작업을 실행하는 문맥 교환은 구분된다.
실행을 안전하게 잠깐 멈춘다
인터럽트를 받아들이면 CPU와 운영체제는 복귀에 필요한 상태를 보존하고 해당 처리 경로로 이동한다. 어떤 사건인지 확인한 뒤 등록된 핸들러가 처리한다. 끝나면 적절한 절차로 실행 상태를 복원한다. Linux의 IRQ 처리 문서는 장치 드라이버 API와 인터럽트 흐름, 하드웨어 제어를 나누어 설명한다.
디스크 읽기를 기다리던 프로그램을 예로 들면, 장치가 완료를 알렸을 때 커널은 요청 결과를 확인하고 기다리던 작업을 실행 가능한 상태로 바꿀 수 있다. 하지만 인터럽트가 도착한 순간 그 프로그램이 즉시 CPU를 얻는 것은 아니다. 처리 시간, 다른 작업 우선순위, 스케줄링이 이후 진행에 영향을 준다.
인터럽트와 예외는 계기가 다르다
외부 장치나 타이머 인터럽트는 현재 명령의 의미와 독립적으로 발생할 수 있는 비동기 사건이다. 페이지 폴트나 잘못된 명령 같은 예외는 보통 실행 중인 특정 명령과 관련된 동기 사건이다. 아키텍처에 따라 용어를 더 넓게 쓰거나 트랩 범주로 묶기도 하므로 해당 문서의 정의를 따라야 한다. 모두 처리 경로로 진입할 수 있어도 발생 원인은 구분된다.
소프트웨어가 명령으로 유발하는 진입도 존재한다. 이를 외부 장치 인터럽트와 같은 비동기 알림으로 생각하면 시스템 호출의 인수와 복귀 규칙을 놓칠 수 있다. 발생 계기, 저장하는 상태, 복귀 위치가 무엇인지 보면 각각의 역할을 명확하게 비교할 수 있다.
잠깐 막는 규칙과 우선순위
마스킹은 특정 인터럽트를 당장 받아들이지 않도록 제어하는 것이다. 중요한 상태 갱신 중 처리 순서를 조정하거나 장치를 관리하는 데 쓰일 수 있다. 그러나 너무 오래 막으면 사건 처리 지연이 늘어난다. 모든 종류의 인터럽트를 같은 방식으로 막을 수 있는 것도 아니며, 보류한 사건을 어떻게 처리할지는 하드웨어와 운영체제 규칙을 따라야 한다.
핸들러는 빠르게 중요한 상태를 확인하고 긴 작업을 별도의 처리 경로로 미룰 수 있다. 인터럽트 문맥에서는 일반적인 작업 문맥과 달리 대기나 잠금 사용에 제약이 있을 수 있기 때문이다. 정확한 제한은 운영체제와 핸들러 종류를 확인해야 한다. 느린 처리를 무작정 인터럽트 안에 넣으면 다른 사건의 응답도 늦어질 수 있다.
폴링은 상태를 주기적으로 또는 반복적으로 직접 확인한다. 인터럽트는 사건이 적을 때 불필요한 검사를 줄이는 데 유리하지만, 사건이 아주 많으면 알림마다 처리 비용이 커질 수 있다. 높은 처리량의 장치에서는 여러 사건을 묶어 알리거나 인터럽트와 폴링을 결합하기도 한다. 한 방식이 모든 부하에서 빠르다고 단정할 수 없다.
인터럽트 수가 많다는 통계는 사건량과 알림 정책, 처리 방식이 함께 만든 결과다. 실제 문제를 찾으려면 처리 시간과 지연, CPU 사용률, 묶음 크기를 함께 봐야 한다. 인터럽트는 CPU가 외부 세계와 효율적으로 협력하도록 하는 실행 제어 장치이며, 사건 감지와 그 사건을 기다린 작업의 실행은 서로 다른 단계다.