OS 인터럽트는 CPU가 외부 장치나 내부의 프로세스에 의해 발생한 이벤트를 처리할 수 있도록 하는 핵심 메커니즘입니다. 이를 통해 프로세서는 다양한 입출력 장치와 효율적으로 상호작용하며, 여러 작업을 동시에 수행할 수 있습니다. 아래에서 인터럽트의 동작 원리, 순서, 종류 및 분석을 좀 더 상세하게 설명하겠습니다.
CPU는 일반적으로 각 명령어를 순차적으로 처리합니다. 하지만 외부 하드웨어 장치나 소프트웨어에서 중요한 작업이 발생하면, 그 작업을 신속하게 처리하기 위해 CPU의 주의를 즉시 끌어야 할 때가 있습니다. 이때, 인터럽트가 발생합니다. 인터럽트는 CPU의 명령어 흐름을 일시적으로 중단시키고, 즉각적으로 중요한 작업을 처리한 뒤 다시 원래의 작업으로 복귀하게 만듭니다.
인터럽트 처리 과정은 다음과 같은 단계로 이루어집니다:
1) 인터럽트 요청 (Interrupt Request, IRQ)
• 하드웨어 장치(예: 키보드, 마우스, 네트워크 카드) 또는 소프트웨어가 CPU에 인터럽트를 요청합니다. 하드웨어 인터럽트는 보통 특정 IRQ 라인을 통해 신호를 보냅니다.
2) 인터럽트 수신 (Interrupt Acknowledgment)
• CPU는 현재 실행 중인 작업을 멈추고, 인터럽트 요청을 수신합니다. 각 CPU에는 인터럽트를 받아들일 수 있는 상태가 있으며, 인터럽트를 수신할 준비가 되었을 때 이를 받아들입니다. CPU는 인터럽트 요청을 수신하면, 다음 단계를 수행합니다.
3) 현재 작업 상태 저장 (Context Saving)
• 인터럽트를 처리하기 위해 CPU는 현재 실행 중인 작업의 상태(프로그램 카운터, 레지스터 값 등)를 메모리에 저장합니다. 이를 **문맥 저장 (context saving)**이라고 하며, 나중에 작업을 재개할 때 사용됩니다.
4) 인터럽트 벡터 테이블에서 핸들러 찾기
• CPU는 인터럽트를 처리하기 위해 **인터럽트 벡터 테이블 (Interrupt Vector Table)**에서 해당 인터럽트를 처리할 루틴, 즉 **인터럽트 서비스 루틴 (ISR)**의 주소를 찾습니다. 인터럽트 벡터 테이블은 각 인터럽트 번호에 대응하는 ISR의 주소를 저장한 테이블입니다.
5) 인터럽트 서비스 루틴 실행
• CPU는 ISR을 실행하여 인터럽트 요청을 처리합니다. 예를 들어, 키보드에서 키가 입력되었다면 CPU는 ISR을 통해 키 입력 데이터를 처리하게 됩니다.
6) 문맥 복원 (Context Restoration)
• ISR이 완료되면 CPU는 메모리에 저장한 이전 작업의 상태를 복원하고, 중단된 작업을 다시 이어서 실행합니다.
인터럽트는 크게 하드웨어 인터럽트와 소프트웨어 인터럽트로 나눌 수 있으며, 하드웨어 인터럽트는 다시 두 가지로 세분화됩니다.
1. 하드웨어 인터럽트
• 비마스크 가능 인터럽트 (Non-maskable Interrupt, NMI): 반드시 처리해야 하는 중요한 인터럽트입니다. 예를 들어, 하드웨어 오류나 시스템 충돌 같은 상황에서 발생합니다. CPU는 이를 무시할 수 없으며, 즉시 처리해야 합니다.
• 마스크 가능 인터럽트 (Maskable Interrupt): 상대적으로 덜 중요한 인터럽트로, 필요에 따라 CPU가 무시하거나 나중에 처리할 수 있습니다. CPU는 특정 시점에서 이 인터럽트를 차단할 수 있습니다.
2. 소프트웨어 인터럽트
• 소프트웨어가 CPU에게 직접 인터럽트를 요청하는 경우입니다. 이는 일반적으로 시스템 호출이나 예외 처리와 같은 이벤트에서 발생합니다. 예를 들어, 프로그램이 파일을 읽거나 쓸 때, CPU에게 이러한 작업을 수행하도록 지시하는 소프트웨어 인터럽트를 발생시킵니다.
인터럽트를 처리하는 방식은 시스템 아키텍처에 따라 달라질 수 있지만, 다음과 같은 일반적인 처리 방식이 있습니다.
1. 폴링 (Polling)
• CPU가 주기적으로 각 장치의 상태를 확인하여 인터럽트가 발생했는지 여부를 감지하는 방식입니다. 이는 간단하지만 비효율적일 수 있으며, CPU 리소스를 낭비할 가능성이 있습니다.
2. 벡터 인터럽트 (Vector Interrupt)
• 각 인터럽트에 고유한 번호가 부여되며, CPU는 그 번호에 따라 ISR을 찾습니다. 인터럽트 벡터 테이블을 사용하여 효율적으로 인터럽트를 처리하는 방식입니다.
3. 중첩 인터럽트 (Nested Interrupt)
• 한 인터럽트가 처리되는 동안 더 높은 우선순위의 인터럽트가 발생하면, 현재 인터럽트를 일시적으로 중단하고 더 중요한 인터럽트를 처리하는 방식입니다. 처리 우선순위에 따라 중요한 인터럽트를 먼저 처리하는 구조입니다.
4. 우선순위 인터럽트 (Priority Interrupt)
• 여러 인터럽트가 동시에 발생할 수 있는 경우, 각 인터럽트에 우선순위를 부여하고, 우선순위가 높은 인터럽트를 먼저 처리합니다.
인터럽트는 다음과 같은 이유로 매우 중요합니다:
1. 효율성: CPU가 멈추지 않고 다른 작업을 수행할 수 있도록 해주기 때문에, 입출력 장치가 CPU의 명령을 기다리지 않고도 데이터를 처리할 수 있습니다.
2. 실시간 처리: 중요한 이벤트가 발생하면 즉시 반응할 수 있는 메커니즘을 제공합니다. 특히 실시간 시스템이나 임베디드 시스템에서는 이러한 빠른 응답이 필수적입니다.
3. 다중 작업: 여러 프로세스와 장치를 동시에 처리할 수 있도록 하여, 멀티태스킹을 가능하게 합니다.
인터럽트와 관련된 문제
• 인터럽트 충돌: 여러 인터럽트가 동시에 발생하면 충돌이 발생할 수 있으며, 이 경우 우선순위 시스템이나 인터럽트 마스크링을 사용하여 문제를 해결합니다.
• 인터럽트 과부하: 너무 많은 인터럽트가 동시에 발생하면 CPU가 과부하 상태에 이를 수 있습니다. 이를 해결하기 위해 인터럽트를 적절히 관리하고, CPU 리소스를 효율적으로 사용해야 합니다.
실제 사용 예시
• 키보드 입력: 키보드를 누를 때마다 키보드는 CPU에게 인터럽트를 발생시켜 입력 데이터를 처리합니다.
• 네트워크 카드: 네트워크 데이터가 도착하면, 네트워크 카드는 CPU에게 인터럽트를 보내 데이터 처리를 요청합니다.
• 디스크 입출력: 파일을 읽거나 쓸 때 디스크 장치는 CPU에게 인터럽트를 보내 데이터를 요청하거나 전송합니다.
결론
인터럽트는 CPU가 시스템 자원과 효율적으로 상호작용하고, 멀티태스킹 환경에서 중요한 작업을 즉시 처리할 수 있도록 도와주는 매우 중요한 메커니즘입니다.