[운영체제] 인터럽트

기영·2024년 6월 29일

운영체제/CS

목록 보기
3/4

인터럽트

인터럽트란 프로세스 실행 중 예기치 못한 상황 발생 시 이를 처리하는 것을 말한다.

"한 프로세스가 실행 중 다른 프로세스가 실행이 되어야 한다면?"
➡ CPU에게 다른 프로세스가 실행이 되어야한다고 알려야한다.

"한 프로세스가 실행 중 메모리 접근에 오류가 생겼을 경우?"
➡ CPU에게 이를 알려야한다.

위와 같이 예기치 못한 상황 발생 시 이를 처리하기 위해 컴퓨터 시스템은 인터럽트를 발생시킨다.

이러한 인터럽트 상황 발생 시, 시스템은 ISR(Interrupt Service Routine)을 실행한다.
개념적인 이해를 위해 ISR은 인터럽트 시 컴퓨터가 수행해야할 동작을 담은 함수라고 보면 된다.

ISR은 인터럽트 벡터 Interrupt Vector에 저장되어 있다.
정확히는 인터럽트 벡터가 ISR의 주소를 포함하고 있는 것이다.

Maskable vs Non-Maskable Interrupt

인터럽트는 Maskable InterruptNon-Maskable Interrupt로 나눌 수 있다.
이는 인터럽트의 우선순위에 따른 구분이다.

Maskable Interrupt는 우선순위가 낮은 인터럽트로써, 앞서 우선순위가 높은 인터럽트에 대한 ISR이 실행 중이었다면 해당 인터럽트는 거부될 수 있다.

Non-Maskable Interrupt는 우선순위가 제일 높은 인터럽트로써, 어떠한 ISR이 실행 중이었든 해당 인터럽트를 실행한다.

External vs Internal Interrupt

또한, 인터럽트는 외부 인터럽트내부 인터럽트로 나눌 수 있다.

External Interrupt

외부 인터럽트는 CPU 외부에서 발생하는 인터럽트이다.
주로 I/O 장치에 의해 발생하는 인터럽트로 예를 들어, 키보드/마우스/프린터/디스플레이/통신/타이머에 의해 발생한다.

따라서, 비동기적인 이벤트를 처리한다고 할 수 있다.

📌 동기 vs 비동기

  • 동기 Sychronous
    실행 시점에서 예측이 가능한 경우
  • 비동기 Asynchronous
    실행 시점에서 예측이 불가능한 경우

키보드 입력, 마우스 입력, 패킷 전달(통신), 타이머는 CPU의 입장에선 프로세스의 실행과는 무관한 이벤트이며, 프로세스 실행시점에서 예측이 불가능하다.

※ 타이머는 우리 입장에선 "예측이 가능하지 않나?"라는 생각이 들지만, 그건 CPU 외부의 우리의 시선에서 보는 것이다. CPU의 입장에선 프로세스와 무관하게 들어오는 인터럽트인 것이다.

Internal Interrupt

내부 인터럽트는 CPU 내부에서 발생하는 인터럽트이다.
즉, 프로세스 실행 중 발생할 수 있는 인터럽트를 이야기한다.
따라서, 프로세스 실행과 관련해 발생하는 이벤트로써 동기적인 이벤트를 처리한다고 할 수 있다.

내부 인터럽트는 크게 3종류로 나눌 수 있다.

1. Fault
인터럽트 발생 시, 현재 명령어(Context)를 저장한다. 이후 ISR을 실행 시킨 뒤 fault가 났던 명령어로 돌아와 계속해서 실행한다.
ex) memory space fault(page/segmentation fault)

위의 설명과 같이, page fault나 segmentation fault로 인해 제대로 실행되지 않았던 명령어가 있으면, page/segmentation에 접근 가능도록 하는 ISR을 실행시킨 뒤 본래 명령어를 실행하는 것이다.

2. Trap
인터럽트 발생 시, 현재 명령어(Context)를 저장한다. 이후 ISR을 실행 시킨 뒤 trap이 발생했던 명령어의 '다음' 명령어로 돌아와 계속해서 실행한다.
ex) system call, exception handling

위의 설명과 같이, system call이나 exception handling 후 해당 명령은 이미 처리가 된 것이므로 ISR 실행 후 그 다음 명령어부터 실행한다.

3. Abort
인터럽트 발생 시, ISR을 실행 시킨 뒤 현재 실행 중인 프로세스(task)를 중단(abort)한다.
ex) divide by zero

위의 설명과 같이, divide by zero와 같은 심각한 문제는 더이상 프로세스 진행이 어려우니 context를 저장할 필요없이 ISR 실행 후 원래 실행 중이던 프로세스를 종료한다.


Interrupt Handling

인터럽트 처리 방식에는 Vectored Interrupt SystemPolling System이 있다.

먼저 예를 통해 2가지 방식을 비교한다면, 예를 들어 프린터가 100장의 프린트를 출력하는 작업을 수행한다고 가정해보자. 인터럽트가 발생되어 프린트를 시작할 것이다.

  • Vectored Interrupt System에서는 프린트를 하는 동안 다른 작업 수행 후, 프린트 완료 시 인터럽트 발생시켜 완료되었음을 알린다.
  • Polling System에서는 프린트가 다 될때까지 다른 작업을 수행하지 못하고 기다린다. 즉, Busy Waiting하는 것이다.

위와 같은 예를 보면 Polling System은 CPU cycle을 낭비한다는 단점이 있어 굳이 써야하냐라는 생각이 들 수 있다.

그러나, Polling System이 가지는 장점은 다음과 같다.

  • 구현이 간단하다.
  • 다른 작업을 수행할 일이 없어, 해당 작업(프린트)을 빨리 끝내 fast response를 제공한다.
  • 다른 작업을 수행할 일이 없어, context switcing overhead가 발생하지 않는다.

다음과 같은 장점이 있기 때문에 Polling System이 언급되는 것이다. 그러나 Busy waiting이라는 치명적인 단점이 존재하기 때문에 Polling 방식은 현재 사용되지 않으며, 이를 사용하는 시스템에서는 다음과 같은 전제조건이 따른다.

  • Fast I/O device : I/O 장치의 속도가 빨라야 한다.
  • Shorter I/O service routine : 문맥 교환 오버헤드보다 ISR 실행 시간이 짧아야한다.
  • Should happen rarely : 자주 일어나지 않아야 한다.

앞서 배운 동기/비동기의 개념을 적용시켜 본다면 다음과 같다.

  • Vectored Interrupt System : 비동기
  • Polling System : 동기

Vectored Interrupt는 인터럽트 후 CPU는 다른 작업들을 수행하며, 인터럽트 처리 작업이 완료되면 다시 CPU에게 인터럽트를 보내는 비동기적 특성을 보인다.
Polling 방식은 해당 인터럽트 처리 작업 동안 CPU cycle을 차지하고 있기 때문에 동기적인 특성을 보인다.

추가적으로 Polling 방식을 Pesudo Code로 나타내면 다음과 같다.

# print start

while(1){ // busy waiting
	if(프린트 갯수가 100장)
    	break;
}

이와 같이 구현은 간단하게 생각할 수 있지만, busy waiting과 계속해서 상태를 확인해야한다는 단점이 생긴다는 것을 알 수 있다.

profile
computer engineering student

0개의 댓글