[OS] 3. Process
Process
Program in execution. 실행시 Main memory로 로드되어 실행된다. 자세한 메모리 구조는 Segment를 보면 된다.
Program은 passive entity이고 process는 active entity다. 꼭 구분하자.
Process State
Process의 State는 5개로 구분한다.
- new
만들어지고 있는 상태 - ready
processor에 적재되기를 대기하는 상태 - running
instruction이 실행되고 있는 상태. 인터럽트 발생시 ready상태로 돌아간다. - waiting
어떤 다른 상황이 발생하기를 기다리는 상태 - terminated
실행이 끝난 상태
PCB(Process Control Block)
아래와 같은 process에 관련된 정보를 포함한다.
- Process State
- Program counter
- CPU Register
- CPU scheduling information
- Memory-management informatino
- Accounting information
- I/O status information
Process Scheduling
Process Scheduling은 queue와 context switch를 통해 이루어진다. 여기서 참고하는 개념이 multi programming, time sharing이다.
Multi programming의 목적은 CPU의 활용을 극대화하기 위함이다. CPU가 idle한 상황을 없애는 것이 목표.
Time Sharing의 목적은 사용자의 입장에서 각 프로그램을 상호작용할 수 있게 하기 위함이다.
Queue
Process Scheduling에서 사용되는 queue는 아래와 같고 여러 queue가 존재할 경우 queue간에 이동도 가능하다.
- Job Queue: Set of all processes
- Ready Queue: Set of all processes loaded into main memory, ready and waiting to execute
- Device Queue: Set of processes waiting for I/O device
Context Switch
실행되고 있는 process를 변경할때 실행되던 process의 정보를 PCB에 저장한다. 교체시간동안 다른 작업은 불가능하고 시간은 하드웨어의 성능에 의존한다.
Scheduler
- Long-term Scheduler(job scheduler)
process를 선택하고 main memory에 적재(dispatch)한다. new $\to$ ready 에서 사용된다.
메모리에 적재하는 역할을 하기 때문에 degree-of-multiprogramming을 결정한다. - Short-term Scheduler(CPU scheduler)
실행할 준비가 된 process(ready)를 선택해 CPU를 할당한다. ready $\to$ running 에서 사용된다.
CPU scheduler를 short-term이라 부르는 이유는 ready process는 자주 CPU 할당을 바꾸지만, job scheduler는 new에서 main memory로 적재하는 상황이 자주 일어나지 않기 때문이다.
- Mid-term Scheduler
메모리가 부족하면 swap out, swap in을 하고 언제든지 돌아갈 수 있다.
Process type
Long-term scheduler는 I/O-bound, CPU-bound 중에서 적당한 비율로 메모리에 적재(new $\to$ ready) 해야한다. 하지만 I/O 작업과 CPU calculation 작업중에 어떤부분이 비중을 많이 차지하는지 실행 전에는 확인할 수 없다.
- I/O bound process: I/O 작업에 시간을 더 할당, short-cpu burst
- CPU calculation: CPU 계산에 시간을 더 할당, long-cpu burst
Process Creation
Process가 생성될때 생성하는 parent, 생성되는 child process로 나눈다. 그리고 Process는 pid로 구분할 수 있다. child process는 pid가 0으로 초기화되어 생성된다.
자원은 OS에서 직접 할당하거나 parent process의 하위자원을 할당받는다. 이때 pc도 같이 할당받기 때문에 실행는 instruction도 같다.
parent process는 child process와 동시에 실행될 수도 있고 wait()을 호출해 child process의 종료를 기다릴 수도 있다.
또한 process는 tree 형태로 보관된다. 메모리 주소는 parent process의 주소를 사용하거나 새로 할당받는다.
fork()로 child process를 만들 수 있고 exec()을 통해 실행한다. 이때 parent process의 메모리주소를 그대로 사용한다.
fork()를 통해 child process를 생성하고 pid를 return받는다. exec()을 통해 실행하고 exit()을 통해 parent process로 돌아간다. parent process는 wait()을 한곳부터 다시 실행한다. 이때 wait(&status)를 통해 return값을 받을 수 있다.
Process Termination
process가 종료하면 exit()을 통해 OS에 삭제를 요청한다. 혹은 child process가 할당자원을 침범하거나 필요 없어질때 abort()를 통해서 parent process가 강제종료하는 경우도 있다.
wait()을 통해 child process의 termination, pid return을 기다린다. 만약 parent가 wait()없이 종료했다면 orphan, parent가 wait()을 하지 않았고 child가 종료했다면 zombie이다.
Interprocess Communication(IPC)
Process는 independent or cooperating으로 구분하는데, cooperating process는 다른 process에 영향을 받거나 준다. 협동하는 이유는 information share, computation speedup, modularity가 있다. 이때 IPC가 필요하고, shared memory나 message passing 방식으로 나눈다.
Shared Memory
memory의 일정 구역을 서로 공유하는것. Message Passing보다 속도가 빠르다. 하지만 cache coherency 문제가 있다.
Producer-Consumer Problem
Producer는 정보를 생산하고 Consumer는 그 정보를 사용한다. 이를 위해 bounded-buffer인 shared memory를 사용하는 것이다. 이를 구현하는데 circular queue를 사용한다.
Message Passing
message를 교환하며 통신하는것. Shared memory보다 구현이 쉽다.
통신을 위해 communnication link를 만들고 message를 send/receive한다. 이때 communication link는 shared memory,hardware bus / [in]direct communication, [a]synchronous comm 등이 있다. Blocking을 통해 synchronous하게 통신하거나 blocking 없이 asynchronous하게 통신할 수 있다.
Direct Communication
자동으로 생성되는 하나의 link를 통해 통신. 이때 서로의 pid를 부르면 Symmetry addressing, sender만 pid를 지정하면 asymmetry addressing이라 한다.
Indirect Communication
message가 mailbox, port를 통해 전달된다.
Buffering
- Zero capacity: buffer 없이 전송하기 때문에 blocking을 무조건 해야한다.
- Bounded capacity: finite lengthed buffer를 사용하고 필요에 따라 blocking해야한다.
- Unbounded capacity: blocking이 없다.