Process라고 하면 흔히 "현재 실행 중인 프로그램"이라고 알고 있다. 그러나 더 깊이 들여다보면 Process도 하나의 자료구조 (data structure)라는 것을 알 수 있다.
지금부터 왜 Process를 자료구조로 여기는지 확인해볼 것이다.
process는 크게 4가지의 영역으로 구분되어 있고 주소공간 (Address space)의 개념으로 관리된다.
이를 그림으로 나타내면 아래와 같다.
(필기는 양해부탁드립니다)
그리고 process의 경우 2가지로 설명할 수 있다.
첫 번째로 I/O-bound process가 있다. 이 경우 hwp, ppt와 같이 user의 입력이 있는 경우 입력할 때마다 CPU가 일하고 입력이 없는 경우 다음 I/O event가 있을때까지 기다린다. 따라서 CPU 사용시간이 매우 짧은 반면 발생 빈도는 높기 때문에 many short CPU bursts라고 표현한다.
두 번째로 CPU-bound process가 있다. 이 경우는 I/O event보다 연산에 더 많은 시간을 사용하기 때문에 I/O bound process와 반대로 발생 빈도가 적고 한번 CPU가 할당되면 최대한 오래한 사용하려고한다. (few very long CPU bursts)
이 둘 중에 어떤 것이 우선이 되어야 할까? 쉬운 예시로 카톡과 소인수분해 연산이 있다. 만약 사용자가 카톡을 하면서 소인수분해를 동시에 하고 있다면, CPU를 어느 프로세스에게 먼저 줘야할지 정해야한다. 이 경우 만약 소인수분해에게 CPU를 먼저 할당해준다면 연산이 모두 끝날때까지 카톡을 못하게 된다. 물론 연산 수행속도가 느린 것은 아니지만, 사용자에게는 둘의 차이가 체감될 것이다. 그렇기 때문에 I/O bound process에게 우선권을 주어야 한다.
Process가 실행을 시작하게 되면 state를 바꿔서 현재 어떤 작업이 진행중인지를 나타낸다.
운영체제가 프로세스를 제어하기 위해 정보(CPU 레지스터 값들)를 저장해 놓는 곳으로 프로세스의 상태 정보를 저장하는 구조체이다. Linux에서는 task_struct 라고 정의하며 PCB에 저장되는 정보는 다음과 같다.
PCB |
---|
Process state |
Program Counter |
CPU registers |
CPU scheduling information |
Memory-management information |
Accounting information |
I/O status information |
interrupt의 과정과 같지만, 위에서 언급한 PCB의 관점으로 설명하면 interrupt가 발생했을 때, interrupt handler에 의해 interrupt 처리가 끝난 뒤 다시 돌아와서 원래의 process를 실행하기 위해 저장을 해야 하는데 그것을 PCB에 한다. 즉 각각의 Process에 대응하는 PCB 번호에 process에 대한 정보를 저장해놓고 그때그때 사용하면서 정보를 저장하고 loading하는 과정을 반복하게 된다.
Scheduler란 쉽게 말해 process들의 일정표를 짜는 방법을 의미한다. 즉 어떤 process에게 CPU를 할당하고 process간의 순서를 정해서 보다 효율적인 CPU 사용과 process의 실행을 가능하게 하는 존재이다.
: 어떤 process를 ready queue에서 가져와야 하는지를 결정하는 scheduler이다.
이 scheduler의 경우 degree of multiprogramming을 제어하고 자주 요청할 필요가 없기 때문에 느리다.
: 어떤 process를 다음에 실행할지를 결정하고 CPU를 할당해주는 scheduler이다. 그렇기 때문에 빈도가 매우 높고 속도가 매우 빨라야 한다.
: Multiprogramming을 위한 작업으로, Memory의 공간을 확보하는 것이 주 목적이다. Swap in/out으로 지금 사용하지 않는 process는 Disk로 보내고 지금 사용할 process를 memory로 가져온다.
CPU가 다른 process로 전환을 하려고 할 때 기존에 실행중이던 process를 어딘가에 저장해두고 새로 실행할 프로세스를 실행해야 기존 process를 잃어버리지 않는다. 이 때 저장하는 공간 (자료구조)이 위에서 언급한 PCB이고 register와 PCB 사이를 왔다갔다 하며 data를 저장하고 load한다. 그러나 Context Switch 역시 overhead이기 때문에 시간이 오래걸리고 hardware에 의존적이다. 따라서 pointer로 context switch를 하는 방식이 떠오르고 있다고 한다.
Thread의 경우 Context Switch에서 발생하는 Overhead를 줄이고자 최대한 공유할 수 있는 data (전역 변수, code 등)는 공유하고 지역 변수나 function call 같이 thread마다 다른 data는 각각의 thread가 실행하도록 하는 방식이다. 이 방식을 통해 Address space만 공유하여 하나의 process에서 여러 작업을 수행할 수 있게 된다.