Dialogue on Virtualization
여기 하나의 복숭아가 있다고 가정해 보자.
나는 이 복숭아를 3명의 사람에게 공유하려고 한다. 이때, 3명의 사람이 다른 사람과 복숭아를 공유한다는 사실을 알면 불쾌할 수도 있다. 따라서 3명의 사람이 각각 자신만의 복숭아를 지급받았다고 생각하도록 해야 한다.
복숭아 - CPU or memory, 3명의 사람 - process이라고 할 때
>>> CPU 또는 memory를 각각의 프로세스가 혼사 소유하고 사용하고 있다고 여기도록 하는 것이다.
어떻게??
3명의 사람은 모두 하루종일 복숭아를 먹지 않을 것이기 때문에, 내가 복숭아를 빼앗아 복숭아가 필요한 사람에게 제공하면 된다.
CPU Virtualization
The Crux of the Problem : How to Provide the Illusion of Many CPUs?
가상화의 핵심은 어떻게 하면 많은 CPU의 illusion을 제공하는가 이다.
Running a Process
process는 Fetch, Decode, Execute, Update PC의 반복으로 실행된다.
Running Multiple Processes
실제로 우리는 하나의 process만 사용하는 것이 아니라 여러 개의 process를 사용한다.
>>> 어떻게 CPU는 이 과정을 수행하는가?
Interleaving Multiple Processes
이런 식으로 CPU는 process A를 조금 수행하다가, B의 코드로 점프, C의 코드로 점프... 이러한 과정을 반복하여 수행할 수 있다. 하지만 이는 가상화가 아니다.
Virtualizing the CPU
CPU 가상화는 OS가 필요에 따라 Code A를 실행하도록 CPU를 넘겨주었다가, 다시 가져오고 B가 사용할 수 있도록 넘겨주었다가, 다시 가져오고... 와 같은 CPU의 주고 가져오기를 반복하는 것이다.
Time sharing
OS가 CPU를 가상화하는 방법 중 하나로 사용자가 여러 process를 동시에 사용할 수 있도록 CPU를 할당하는 것이다. 한 process를 실행할 때, 다른 process를 잠시 멈추고 이러한 과정을 반복하는 기술이다.
What is a Process?
process는 실행 중인 program의 instance이며, address space라는 가상공간인 memory에 올라간다.
protection의 기본 단위이며, 고유의 ID(PID)를 가지고 있다.
process는 CPU context, OS resources, 그리고 그 외의 PID, state,... 등의 정보를 가지고 있다.
**Program counter : instruction의 주소를 가리킨다.
**Stack pointer : return address를 다루기 위해 Stack을 가리키는 pointer
process가 포함한 자원들은 program이 끝이나도 남아있다. 따라서 OS가 처리해줘야 한다.
Process Creation
1. disk에 저장되어 있던 program code(당장 필요한 것만 >>> lazily하다.)를 memory에 load 한다.
이때 load 되는 곳은 process의 address space이다. program은 disk 같은 저장소에 executable format(실행파일 형식)으로 저장되어 있다.
2. program의 run-time stack이 할당된다. 이때, stack은 지역변수, 함수의 인자 또는 return address 등을 저장할 때 사용한다. argc 및 main()의 argv array로 stack 초기화
3. program의 heap 구역이 생성된다. 동적 할당에 의해 생성된다. malloc(), free()가 사용된다.
** heap 구역 : 필요에 의해 동적으로 memory를 할당할 때 사용
4. OS는 추가 초기화 작업을 시행한다. ex. I/O setup
5. program을 main()이라고 불리는 entry point로 진입해 시작한다.
Process Hierarchy
process 계층은 parent-child관계이다. 하나의 process가 다른 process를 생성할 수 있다.
Unix에서는 process group, Window에서는 process 계층 개념이 없다.
process 목록 찾기 >>> Unix는 ps, Window는 taskmgr(작업관리자)
Process Creation
fork()는 새로운 process를 생성해 parent process를 복제하는 것이다.
parent process는 open files, UID 등 대부분의 resource 및 권한을 상속한다. parent는 wait()를 사용해 child가 완료가 될 때까지 기다린다. 또는 병렬적으로 계속 작업할 수 있다. Shell 또는 GUI는 내부적으로 이 system call을 사용한다.
exec()는 현재의 process image를 새로운 program으로 바꾼다.
Window에서 새로운 process를 만들기 위해서는 fork()와 exec()를 모두 생성한다.
Process Termination
- Normal exit (voluntary)
- Error exit (voluntary)
- Fatal error (involuntary)
- Segmentation fault - illegal memory access
- Protection fault
- Exceed allocated resources, etc.
- Killed by another process (involuntary)
- By receiving a signal
- Zombie process : terminated, but not removed
종료에는 정상 종료, 자발적 종료(프로그램 내부 로직에 따라), 강제 종료(외부에서 강제로 종료시킴)가 있다.
Process States
process는 3가지 상태 중 하나일 수 있다.
1. Running : process가 processor에서 실행되고 있는 상태
2. Ready : process가 실행될 준비가 끝났지만, 아직 OS가 이 process를 실행하지 않는 상태
3. Blocked : 일반적으로 I/O 요청이 필요할 때이다. process가 일종의 작업을 수행했지만, 다른 I/O 요청이 있으면 잠시 대기상태에 있다가 I/O요청이 끝나면 ready가 되어 OS의 선택을 기다린다. (대기상태라고 생각)
위의 2가지 경우를 살펴보면
CPU만 사용하는 경우는 running과 ready,
CPU사용과 I/O요청을 포함하는 경우는 running, ready, Blocked 상태가 있는 것을 볼 수 있다.
Implementing Processes
- PCB (Process Control Block)process의 정보를 저장하기 위해 PCB data structure를 사용한다.
The xv6 kernel Proc Structure
process가 사용하는 Data structure
Context Switch
context switch는 한 process에서 다른 process로 CPU를 전환하는 작업이다.
옮기기 전에 했던 동작들을 백업하고 기존에 쓰던 data를 비워줘야 하기 때문에 overhead를 동반한다.
overhead는 hardware의 도움을 받아야 overhead를 크게 줄일 수 있다. overhead의 크기는 hardware의 크기에 따라 다르다.
Performing Context Switch
Process State Queues
- The OS maintains a collection of queues that represent the state of all processes in the system
- Ready queue (or run queue)
- Wait queue(s) : one queue for each type of event (device, timer, message,...)
- Each PCB is queued onto a state queue according to its current state
- As a process changes state, its PCB is migrated between the various queues
OS는 여러 개의 process를 관리하기 위해 Queue를 사용한다.
fork()
int fork ()
fork() 동작과정
- Creates and initializes a new PCB
- Creates and initializes a new address space
- Initializes the address space with a copy of the entire contents of the address space of the parent
- Initializes the kernel resources to point to the resources used by the parent (e.g. open files)
- Places the PCB on the ready queue
- Returns the child's PID to the parent, and zero to the child
fork()를 호출하면 process를 그대로 복사해서 process를 생성한다.
생성된 process는 자식 process이다.
exec()
int execv ( char *prog, char *argv [] )
exec() 동작과정
- Stops the current process
- Loads the program "prog" into the process' address space
- Initializes hardware context and "args" for the new program
- Places the PCB on the ready queue
- exec() does not create a new process
- What does it mean for exec() to return?
exec()는 새로운 process를 만들지 않는다.
exec()는 code와 static data를 load 해서 자신의 code segment와 data segment에 overwrite 한다.
Policy vs Mechanism
cpu 가상화에서는 policy와 mechanism이 둘 다 필요하다.
- Policy ( What should be done? )
- 의사결정을 하게 될 때 policy를 따른다.
- Mechanism ( How to do something? )
- 어떤 일을 어떻게 구현할 것인가?
Separating Policy from Mechanism
mechanism에서 policy를 분리하는 것은 OS 설계의 핵심원칙이다.
policy는 workload에 환경에 따라 (workload, places, over time...) 변경될 가능성이 높다.
policy와 분리된 mechanism이 더 바람직하다.
모듈식 OS 구축을 할 수 있고, 확장 가능한 system을 사용할 수 있다.
부산대학교 안성용 교수님의 강의를 복습하기 위한 글입니다.
복습용 글이기에 정확하지 않을 수 있다는 점 유의하시길 바랍니다.
'CS > 운영체제' 카테고리의 다른 글
Mechanism : Limited Direct Execution (0) | 2023.05.14 |
---|---|
Introduction to Operating Systems (0) | 2023.04.12 |