기본적으로 CPU는 하나당 한 가지의 일밖에 동시에 처리할 수 없다.
때문에 메모리에 두 개 이상의 프로그램을 배치했다고 하더라도 두 개의 프로그램이 동시에 실행될 수는 없다.
결국 멀티 태스킹을 구현하기 위해서는 아주 짧은 시간동안 한 프로세스를 실행하다가 다른 프로세스로 CPU를 사용할 수 있도록 넘겨주는 것을 반복해야 한다. 이를 간단하게 구현하기 위해서는 각 어플리케이션마다 중간에 '전환점'을 만들어 두면 된다. 전환점은 '내 처리를 잠시 멈추고 CPU를 다른 프로세스에게 배정할 적당한 때가 왔다'라는 것을 알리는 것으로, OS에게 특정 System Call을 호출하여 다른 프로세스에게 CPU를 배정하는 일을 하게 만든다. 이렇게 OS가 각 애플리케이션의 처리를 나눠서 조금씩 실행시키는 기능을 '디스패치(Dispatch)'라고 부른다.
하지만 이런 방식으로 CPU를 나눠 쓰며 멀티태스킹을 구현하게 되면 문제가 생긴다.
'전환점'은 어플리케이션이 직접 호출하는 것이므로 어플리케이션 설계 단계에서 어디가 전환점인지를 알아야 한다. 다시 말해서 CPU 배분이라는 OS 고유의 권한을 어플리케이션 설계자에게 전가할 수밖에 없다는 것이다. 또한 '전환점'을 사용하게 되면 이 '전환점'이 호출되기 전에는 절대로 다른 프로세스에게 CPU가 배분되지 않는다는 문제도 발생한다. 따라서 다른 방법을 사용해서 멀티태스킹을 구현할 필요가 있게 되는데, 이후에는 따로 '전환점'의 System Call을 사용하지 않고 어떤 것이든 System Call을 사용한다면 즉시 Dispatch가 일어나도록 했다.
하지만 이 방식에도 문제가 많다.
시스템 콜을 잘 사용하지 않고 연산만을 많이 수행하는 프로그램이나 소프트웨어상의 결함으로 무한 루프에 빠져버려 시스템 콜을 호출하지 않는 프로세스가 있다고 가정하면 다른 프로세스는 CPU를 할당받을 수가 없게 된다. 이를 방지하기 위해 최종적으로 CPU는 타이머와 끼어들기(interrupt)를 이용한 멀티 태스킹을 구현했다. 끼어들기는 CPU가 어떤 작업을 진행하고 있어도 이것을 강제로 중단시키고 OS로 돌아와 다른 프로세스에게 CPU를 할당할 수 있도록 하는 신호를 의미한다.
OS는 어플리케이션으로 CPU 제어를 넘기기 전에 항상 타이머를 설정하여 일정 시간 이후 끼어들기가 발생하도록 한다.
그러면 어플리케이션으로 제어가 넘어간 후에 무한 루프나 긴 연산으로 System Call이 발생하지 않더라도 일정 시간 후에는 강제적으로 OS로 제어를 되돌릴 수 있다.
이렇게 타이머 끼어들기를 사용하는 프로그램 전환 방법을 시간을 짧게 구분해서 애플리케이션끼리 서로 나눈다고 하여 '시분할 시스템'이라고 한다. 앞에서 언급한 시스템 호출을 계기로 CPU를 재배정하는 방식의 멀티 태스킹은 다른 타 어플리케이션의 존재를 의식하고 계속 System Call을 호출해주지 않으면 작동할 수 없기 때문에 '협조적 멀티태스킹'이라고 부르며, 시분할 시스템처럼 타 어플리케이션의 중단을 기다릴 필요가 없는 멀티태스킹 방식을 '비협조적 멀티태스킹'이라고 부른다. 또한 이런 '비협조적 멀티태스킹'은 다른 어플리케이션의 중단을 기다리지 않고도 처리를 가로챌 수 있다는 점에서, 즉 '먼저 취할 수 있다'는 점에서 '선점 멀티태스킹(Preemptive multitasking)'이라고도 하며, 그 반대로 다른 어플리케이션의 처리를 먼저 취할 수 없는 멀티태스킹을 '비선점 멀티태스킹'이라고 한다.
'Knowledge' 카테고리의 다른 글
Memory Segmentation (0) | 2016.12.27 |
---|---|
NAT와 NAPT의 개념과 원리 (10) | 2016.12.01 |
PCB (Process Control Block) (0) | 2016.11.14 |
[Assembly] Intel x86, Local JMP [0xE9] (0) | 2016.11.07 |
[BigData] Spark 공부 (0) | 2016.10.19 |