1. Process Concepts
Process란
-
Why?
하나의 프로그램이 복잡해지면서 하나의 문제를 여러개의 task (desing-time entity)로 나누어 해결하는 decomposition이 중요해진다.
-
What?
Program은 instruction sequence이다. 이를 load하여 memory, CPU, I/O와 같은 resource를 차지하면 process라 부른다. 즉, processs는 program in execution이라 할 수 있다.
-
Multiprogramming vs Multiprocessing
Multiprogramming은 memory에 process가 여러개 load되어 있는 것을 말한다. Multiprocessing은 여러개의 process가 같이 수행되고 있음을 말한다.
Process Control Block (PCB)
- Program = Data Structure (State) + Algortihm (Operation)과 같다. 이 중 process의 data structure를 구현한 것이 PCB이다.
- Process는 memory context (code, data, heap, stack), HW context (registers), System context(Process table, open file table, page table) 세가지 context를 가진다. 이러한 정보는 PCB에 저장된다.
State Transition![](https://velog.velcdn.com/images/eunie/post/263d92d6-c11a-484f-a132-5894c3901e35/image.png)
- 처음 생성된 process의 state은 ready이고, CPU를 할당받으면 running이 된다. 이때, 키보드 입력과 같은 asynchronous한 HW interrupt를 받으면 ready state으로, system call이나 I/O와 같은 SW interrupt를 받으면 waiting state으로 바뀐다. Waiting state에서 기다리던 일을 마치면다른 process가 CPU를 사용하고 있을 수 있기 때문에 ready state으로 간다.
- 각 state는 process들의 PCB를 node로 가지는 queue를 가진다.
2. Process Scheduling
Scheduler Design![](https://velog.velcdn.com/images/eunie/post/8909f66a-8a29-49d2-a6f6-7c841f3ad377/image.png)
- 여러 개의 process가 동시에 수행될 때에는 OS가 다음에 수행될 process를 선택하고 자원을 할당해주어야 한다. 이때, fair scheduling & protection이 중요하다.
- 누구에게 cpu를 할당할 것인가에 해당하는 Scheduler Policy와 어떻게 안전하게 switch할 것인지에 해당하는 Dispatcher Mechanism 두가지로 나누어 생각할 수 있다.
Dispatcher
- Kernel
한 process에서 다른 process로 넘어가는 것은 kernel이 control한다. kernel이라는 active process가 수행 중인 process를 지켜보다가 다른 process로 switch해준다고 오해할 수 있지만, OS는 kernel mode에서만 수행가능한 함수들의 집합체 library에 가깝다.
- How to enter kernel mode?
Traps (syscall, error, page fault), Interrupt (키보드 입력, I/O completion, timer) 가 발생하면 OS가 control을 갖게 된다.
Processor Status Word (PSW)의 mode bit에 mode를 저장한다.
![](https://velog.velcdn.com/images/eunie/post/7bcedb04-71c7-45e6-9902-310f91d86df8/image.png)
- System Call
System call은 kernel mode에서만 수행할 수 있는 함수이다. process는 user context/kernel context/interrupt context 각각에 대한 stack을 잡는다. Syscall로 kernel 함수를 호출하면, stack의 mode가 바뀌는 것일뿐 주체는 여전히 user process이다.
- cf) ISR에서 syscall인 read()를 호출하면?
어떤 process에 interrupt가 걸리면 interrupt context에서 ISR를 수행한다. ISR는 process가 아닌 context와 stack만 가지는 상태이다. 즉, read()와 같이 blocking syscall을 하면, scheudling할 수 있는 entity가 없기 때문에 kenrel panic이 발생한다.
→ Interrupt를 통해 Dispatcher가 control을 얻고 context를 switch해준다.
3. Context Swtiching
What must get saved?
- Interrupted process는 다음 process로 cpu를 넘겨주기 전에 기존의 state을 대피시켜야 한다.
- system context, memory context, HW context 세가지 context 중 HW context (register)를 memory에 대피시킨다.
- Memory는 multiprocessing을 지원하기 때문에 각 process는 각자 memory를 가져 switching할 필요는 없다. physical memory가 부족하면 swapping하기도 한다.
Mechanism
1) PSW (mode bit), PC (return address)를 HW적으로 stack에 저장
2) IRQ에 해당하는 ISR로 jump
3) PUSHA instruction을 통해 SW적으로 register(AX~ES) 대피
4)OSPCBCur는 새로운 process의 PCB를 가리키고, CPU's SP에 새로 얻은 stack의 SP를 copy
5) 저장해둔 register pop하고 PC로 jump
cf) process가 create되었을 때에는 저장해둔 register값이 없기 때문에 fake값을 가진 stack을 만든다.
4. Creation and Termination
Creation
- From Scrath (Windows) vs Cloning (Unix)
- Process 0만 from scratch로 만들고, 나머지 process는 fork()를 통해 parent process를 clone한다. clone할 때에는 memory와 PCB를 copy한다.
![](https://velog.velcdn.com/images/eunie/post/3a10d2e9-7f09-4dcc-b598-b9cf3f62ba1e/image.png)
pid = fork()
if (pid < 0) {
perror("failed");
exit(-1);
}else if (pid == 0){
exec(cmd)
}else{
wait(pid)
}
- Why fork?
process간 shared memory가 없어 data를 주고 받기 어려워 pipe라는 file을 만들어 주고 받으려 했다.
ipc_proc() {
fd = open("./fifo_pipe", O_RDWR);
pid = fork();
if(pid > 0){
write(fd, data, size);
} else if(pid == 0) {
read(fd, data, size);
}
}
- Drawbacks
기존의 deep copy based cloning은 매우 expensive하여, pointer만 copy하는 shallow copy를 하고 copy-on-write (COW)를 한다. 이는, read-only로 설정해놓고 write하려 할 때 interrupt가 발생하여 kernel이 수행한다.
Termination
- exit( ) : process가 스스로 종료하고 zombie state라는 정보만 남겨둔다. parent process가 wait()을 통해 주워가기를 기다린다.
- abort( ) : parent process가 강제 종료