● 프로세스의 문맥 (context)
특정 시점을 놓고 봤을 때, 이 프로세스가 어디까지 실행을 했는지 저장하고, 새로운 프로세스를 실행시키기 위해 필요한 정보들이다.
프로세스의 문맥(context)은 크게 세 가지로 구분된다.
- CPU 수행상태를 나타내는 하드웨어 문맥 : Program Counter, 각종 Register
- 프로세스의 주소 공간 : code, data, stack
- 프로세스 관련 커널 자료구조 : PCB, Kernel Statck
프로세스가 실행이 되면 그 프로세스만의 독자적인 주소공간(code, data, stack)을 형성하고, 특정 프로세스가 CPU를 잡게 되면 Program Counter Register가 이 프로세스의 코드 어느 부분을 가리키고 있으며, 매 순간 Instruction을 하나씩 읽어서 CPU안으로 부른다. Register에 해당 데이터를 넣고 산술 연산 장치(ALU)에서 연산을 하고 그 결과를 레지스터에 저장하거나 바깥 메모리에 저장을 한다.
이렇게 진행하다가 어느 특정 시간에 이 프로세스가 어디까지 와있는가를 규명하는데 필요한 요소가 프로세스 문맥이다. 현재 시점의 프로세스의 문맥을 나타내기 위해서는 PC가 어디를 가리키고 있는지, 프로세스의 메모리에 어떤 내용을 담고 있는지, 함수를 호출했을 경우에는 어디까지 쌓아놓고 있는지, 데이터에 변숫값에는 어떤 값이 저장되어 있는지.. 에 대한 것들을 모두 알고 있어야 프로세스의 현재 상태를 알 수 있다. 즉, 프로세스의 문맥이라는 것은 프로세스의 현재 상태를 나타내는데 필요한 모든 요소를 일컫는다.
프로세스 문맥은 크게 세 가지로 나뉜다.
1. CPU 수행상태를 나타내는 하드웨어 문맥 (Program Counter, 각종 register)
CPU와 관련된 상태를 나타내기 위한 문맥이다. 프로세스는 CPU를 잡고 매 순간 Instrucion을 실행한다. 현재 시점에 program counter가 어디를 가리키고 있는지, 각종 Register에는 어떤 값을 넣고 있었는지에 대한 정보이다.
· Program Counter : 프로세스가 Instruction을 어디까지 실행되었는지 카리킴
2. 프로세스의 주소 공간 (code, data, stack)
메모리와 관련된 정보를 알기 위한 문맥이며, code, data, stack으로 이루어져 있다.
3. 프로세스 관련 커널 자료 구조 (PCB, Kernel stack)
운영체제와 관련된 정보를 알기 위한 문맥이다. 커널 Data에는 여러 프로세스의 PCB가 있다. 프로세스가 생길 때마다 운영체제는 그 프로세스를 관리해야 하는데, 프로세스를 관리하기 위해 프로세스의 PCB를 갖고 있는 것이다. 해당 프로세스에게 메모리를 얼마나 줘야 할지, CPU 제어권을 얼마나 줘야 하는지, 혹시나 나쁜 짓을 하고 있지는 않은지 등을 관리하는 역할을 하고 있다.
커널 스택에는 커널 함수를 실행하게 되면 관련 정보들이 쌓인다. 커널도 함수로 이루어져 있기 때문에 함수를 실행하게 되면 그와 관련된 정보들이 스택에 쌓이는 것이다. 각 프로세스가 할 수 없는 일 (I/O작업 또는 System Call)을 요청하게 되면 Program Counter는 커널의 주소 공간 중 Code 영역을 가리키며 커널 코드를 실행한다. 커널 코드는 여러 프로세스들이 공유할 수 있다. 어떤 프로세스든 간에 운영체제 커널한테 요청할 수 있다는 뜻이다. 그렇게 되면 커널은 누구의 부탁을 받고 실행하는지 매번 다르기 때문에, 커널에서 함수 호출이 이루어져 스택에 정보를 쌓을 때에는 프로세스별로 스택을 따로 두고 있다. 프로세스의 현재 상태를 알기 위해서는 User Stack 뿐만 아니라 Kernel Stack에 어떤 내용을 쌓고 있는지 정보가 필요한 것이다.
· 프로세스도 자기 자신의 코드를 실행 중일 때에 함수 호출이 이루어지면 본인 주소공간의 스택에다가 관련 정보를 쌓아 놓음
● 프로세스의 상태 (Process State)
프로세스는 CPU제어권에 따라 상태가 변경되며 실행되며, CPU를 잡고 있느냐, 기다리느냐, I/O 작업 같은 오래 걸리는 작업을 하고 있느냐에 따라 상태는 크게 Running, Waiting, Ready로 구분된다. (경우에 따라 New, Terminated도 추가됨)
- Running : CPU를 잡고 Instruction을 수행중인 상태
- Ready : 메모리 등 다른 조건을 모두 만족 한 후, CPU를 기다리는 상태
CPU가 실행해야 할 프로세스는 여러 가지가 있는데 CPU는 하나밖에 없기 때문에 CPU 제어권을 얻기 위해 기다리는 상태이다. 조건을 만족해야 한다는 말은 필요한 부분은 적어도 물리적인 메모리에 올라와 있어야 한다는 뜻이다. 필요한 메모리가 물리적 메모리에 올라와 있어야 CPU 제어권을 얻었을 때 Instruction을 실행할 수 있기 때문이다. 즉, Ready 상태라는 것은 다른 모든 준비는 다 끝나있고 CPU만 얻으면 바로 Instruction을 실행할 수 있는 상태를 말한다.
- Blocked (wait, sleep) : CPU를 주어도 당장 Instruction을 수행할 수 없는 상태
프로세스 자신이 요청한 Event (I/O 요청)가 만족되지 않아 기다리는 상태이다. 예를 들어, 오래 걸리는 I/O 작업을 한다거나 디스크에서 어떤 정보를 읽어와야 하는데 해당 요청이 완료되지 않으면 다음 Instruction을 실행할 수 없다. 또한, 물리적 메모리 영역에 프로그램 전체 메모리를 올려놓고 실행하지 않는다. 만약 어떤 프로그램의 코드를 실행하려고 했는데 해당 코드가 물리적 메모리에 올라와있지 않고 하드 디스크에 내려가 있으면 Instruction을 할 수 없다. 이러한 상태를 Blocked 상태라고 한다.
- New : 프로세스가 생성중인 상태
- Terminated : 수행이 끝난 상태
프로세스가 생성되면 Ready 상태가 된다. 최소한의 메모리는 물리적 메모리에 올라가 있어야 하며, CPU만 얻으면 프로세스 실행이 가능한 상태이다. CPU 스케줄링에 따라 본인의 차례가 되어 CPU를 얻게 되면 Running 상태가 된다. Running 상태에서 빠져나가는 화살표는 세 가지 정도가 있다. 첫 번째는 자진해서 CPU를 내려놓는 경우가 있다. I/O 와 같은 오래 걸리는 작업을 수행하는 경우에는 I/O 응답이 오기 전까지 Instruction을 하지 못하기 때문에 스스로 Waiting (Blocked) 상태로 넘어간다. 두 번째 경우로는 스스로 CPU 제어권을 내려놓지 않고 CPU를 계속해서 사용하고 싶지만 Timer 인터럽트가 걸려와서 할당된 시간이 끝나 CPU를 빼앗기는 경우이다. CPU 제어권을 빼앗기게 되면 다시 Ready 상태가 되어 CPU 제어권을 얻을 때까지 기다린다. 마지막으로는 프로그램이 끝나 Terminated 되는 경우이다.
● 프로세스를 실행하는 과정
CPU는 빠르게 여러 프로세스가 공유하는 자원이다. 프로세스가 각 Queue에 오가며 실행되는 과정을 살펴보자.
CPU는 Ready Queue에서 프로세스를 넣었다가 꺼내는 과정을 반복한다. 프로세스가 CPU에 있다가(Running 상태) 디스크에서 데이터를 읽어와야 하면 이 프로세스의 상태는 Running에서 Blocked 상태로 바뀌면서 Disk를 읽기 위해 Disk Device Queue에 가서 줄을 선다. Disk 작업이 끝나면 Disk Device Controller가 CPU에 인터럽트를 걸어서 I/O의 완료를 알려준다. 그럼 인터럽트가 들어왔으니 CPU는 잠시 하던 일을 멈추고 운영체제로 넘어가 프로세스 상태를 Blocked에서 Ready 상태로 변경시키고 해당 프로세스는 다시 Ready Queue에 가서 줄을 서있게 된다. 또한, 프로세스가 Running 상태에 있다가 Timer 인터럽트가 들어오면 해당 프로세스는 Reday Queue에서 기다린다. (하드웨어)
공유 데이터를 여러 프로세스가 동시에 접근하면 일관성이 깨질 수 있다. 어떤 프로세스가 공유 데이터를 사용하고 있으면 다른 프로세스가 공유 데이터로 접근을 막아주기 위해 Resource Queue에 줄을 세운다. (소프트웨어)
→ 오래 기다려야 하는 작업이 있으면 프로세스는 Blocked 상태가 되며, 그 작업의 종류(Disk, 키보드, 공유데이터)에 따라 해당 큐(Disk Queue, Keyboard Queue, Resource Queue)에 가서 줄을 서있게 되며, 해당 작업이 완료가 되면 Ready Queue로 넘어가 CPU를 얻을 수 있는 Ready 상태가 된다.
운영체제 커널 주소 공간의 데이터 영역에 자료구조로 Queue를 만들어 놓고 프로세스 상태를 바꾼다. Ready Queue에 있는 프로세스 중에서 CPU를 주고, Blocked에 있으면 CPU를 주지 않는 방식이다.