note title

인터럽트

인터럽트는 무엇일까? 인터럽트, 영 단어 그 자체로, Interrupt. 방해한다는 뜻이다. 정상적인 프로그램의 실행을 방해하는 것을 의미한다. 우리는 이런 상황을 자주 마주하는데, 즐거운 얘기 중에 갑자이 맥을 끊고 자신에게 집중하라고 하는 친구가 있다면, 이 새X, 이 분이 바로 인터럽트라고 볼 수 있겠다. 인터럽트가 발생한 후 모든 사람들은 이 분에게 집중한 이후, 이 분의 관심 요구 사항이 끝난다면 다시 원래의 얘기로 다시 돌아올 것이다. 바로 이 흐름이 CPU와 인터럽트의 관계다.

다시 인터럽트를 말하자면, CPU가 수행 중인 작업을 일시 중단 시키는 일종의 신호라고 볼 수 있다. 인터럽트도 일종의 신호인 만큼 다양한 환경에서 발생하는데, 크게 동기 인터럽트 (synchronous interrupt)비동기 인터럽트 (asynchronous interrupt) 로 나누어진다. 동기와 비동기는 여기서 확인할 수 있다.

동기 인터럽트

동기 인터럽트(Synchronous interrupt)는 CPU에서 발생된다. 일반적인 인터럽트라고 보면 되는데, CPU가 수행 중인 작업을 멈추게 만드는 신호다. 우리가 코드를 짤 때 컴파일이 잘못됐거나 타입을 잘못 명시할 경우 Error가 발생하면서 코드가 멈추지 않는가? 이게 바로 동기 인터럽트다. 예외적인 상황이나 프로그램의 오류에 의해서 발생한다. 쉽게 말해 CPU 내 Exception이다.

비동기 인터럽트

비동기 인터럽트 (asynchronous interrupt)는 주로 입출력 장치에 의해 발생한다. 작업의 알림과 같은 역할을 한다. 입출력 장치도 하드웨어이기 때문에, 하드웨어 인터럽트라고 한다.

하드웨어 인터럽트

CPU는 효율적으로 명령어를 처리하기 위해 하드웨어 인터럽트를 사용한다. 우리가 자주 사용하는 전자레인지를 예로 들어보자. 우리는 전자레인지에 음식을 넣고 돌리는 동안 다른 일을 한다. 그리고 완료가 되는 소리에 의해 전자레인지에서 음식을 꺼낸다. 여기서 완료되었다고 알림을 보내는 것이 하드웨어 인터럽트다. 만약에 하드웨어 인터럽트를 사용하지 않았다면, 우리는 계속해서 전자레인지를 확인해야 하기 때문에 다른 일을 하지 못하는 매우 비효율적인 행동을 해야 한다. (주기적으로 확인하는 기법: polling). CPU도 마찬가지다. 여러 종류의 인터럽트가 있기는 하지만, 처리하는 순서는 동일하다.

  1. 입출력장치 CPU에게 인터럽트 요청 신호
  2. CPU는 실행 사이클을 종료, 인터럽트 여부 확인
  3. CPU는 인터럽트 요청 확인 후 인터럽트 플래그를 통해 인터럽트 수용 여부 확인
  4. 가능하면 CPU가 작업 백업
  5. CPU는 인터럽트 백터를 참조, 서비스 루틴 실행
  6. 루틴이 끝나면 백업된 작업 재개

반대로, Polling 기법은 장치가 아닌 CPU가 직접 장치를 주기적으로 체크하는 방식이다.

하드웨어 인터럽트가 “알림을 기다리는” 방식이라면, 폴링은 “직접 계속 확인하는” 방식인 셈이다. 단순한 시스템이나 테스트 환경에서는 유용하지만, 자원 낭비 측면에서 비효율적이기 때문에 잘 사용하지 않는다.

인터럽트는 매너 없이 CPU의 작업을 무작위로 끊지 않는다. 인터럽트를 해도 괜찮을 지 아주 Gentle하게 CPU에게 여쭤본다. 이 여쭤보는 행동이 바로 인터럽트 플래그이다. CPU가 인터럽트 요청을 수행하려면 플래그 레지스터의 인터럽트 플래그가 활성화 되어 있어야 한다. 만약 불가능이라면 인터럽트 자체를 무시해 버리게 될 것 이다.

그렇다고 플래그 레지스터만 따라서 인터럽트 처리를 하는 것이 아니다. 만약 Critical한 인터럽트가 발생됐을 경우에는 어떠할 것인가? 그래서 무시할 수 없는 인터럽트와 무시할 수 있는 인터럽트가 존재하게 된다. 쉽게 말해 정전이나 하드웨어의 고장일 경우는 무시할 수 없는 인터럽트고, 이런 상황에서는 플래그 레지스터의 활성화 여부와 상관 없이 인터럽트가 발생한다.

CPU가 인터럽트를 받아들인다고 해보자. 그렇다면 CPU 또한 인터럽트를 처리하기 위한 서비스가 한데, 이것이 인터럽트 핸들러 (서비스 루틴) 이다. 어떤 인터럽트를 어떻게 처리하고 작동할 지 정보로 이루어진 프로그램이다.

하드웨어 인터럽트 즉, 입출력 장치마다 입출력을 처리하기 위한 동작이 모두 다르다. 장치마다 루틴이 있기 때문이다. 하지만 하나의 컴퓨터에는 여러 장치들이 연결되어 있기 때문에 이 걸 분리해야 하는데, 인터럽트 벡터가 이 것들을 분리해버린다.

인터럽트는 메모리에 저장을 한다. 하드웨어 인터럽트 요청을 받은 대상으로부터 인터럽트 벡터를 전달 받고, CPU에게 메모리에 저장된 인터럽트 시작 주소를 반환한다. 이러한 흐름으로 각 장치마다 인터럽트 프로그램을 전달, 실행할 수 있게 된다.

CPU는 인터럽트를 실행하기 앞서, 모든 작업들을 백업해야 인터럽트 후 재개를 할 수 있다. 우리가 서로 얘기를 할 때 그 내용을 머리 속에 기억하는 것처럼 말이다. 따라 CPU는 현재 프로그램을 재개하기 위해서 메모리 내 스택(Stack) 에 백업한다. 그리고 마찬가지로 인터럽트 서비스 루틴을 실행하고 다시 스택에 저장해둔 프로그램 카운터등을 다시 불러와 재개하는 흐름을 보이는 것이다.

인터럽트의 예외, Exception

동기 인터럽트는 Exception과 동일하다고 했다. 그 종류에는 여러가지가 있는데, Falut, Trap, Abort, Software Interrupt가 있다.

동기 인터럽트
폴트 (falut)예외가 발생한 명령어부터 실행
트랩 (trap)예외가 발생한 명령어의 다음 명령어부터 실행
중단 (abort)프로그램을 강제로 중단시킬 수 밖에 없을 경우
소프트웨어 인터럽트시스템 콜이 발생했을 때 발생하는 예외




참고자료

※ 이 글은 『이것이 컴퓨터 과학이다』 책을 기반으로, 다양한 자료를 참고해 작성했습니다.