8.2 Processes (프로세스)
Exception은 OS kernel에서 process라는 개념을 제공하기 위한 가장 기본적인 building block이다.
Modern system에서의 프로그램
- 프로그램을 실행시키면, 마치 processor와 memory를 독접적으로 사용하고 있는 것처럼 보인다.
- 이러한 환상은 process라는 개념에 의해 우리에게 제공된다.
precess란
- 전통적으로 process의 정의는 an instance of a program in execution 이다.
- 각 프로그램들은 context 안에서 실행된다.
- context란? 프로그램이 정상적으로 실행하는 데에 필요로 하는 상태들로 구성된다.
- memory상의 program의 code와 data
- stack,
- general purpose register들의 내용들
- PC
- 환경 변수들
- open file descriptor들
- user가 shell에 executable object file의 이름을 입력할 때마다, shell은 새로운 process를 생성하고, 이 새로운 process의 context안에서 이 executable object file을 실행한다.
- OS가 어떻게 process를 구현하는지에 대한 것은 우리의 범위 밖에 있다. 그럼 우리는 어디에 초점을 맞출 것인가?
- 내 프로그램이 독점적으로 processor를 점유하고 있다고 착각을 주는 logcial control flow를 알아볼 것이다.
- 내 프로그램이 독점적으로 memory를 사용하고 있다고 착각을 주는 memory system에 대해 알아볼 것이다.
- 이러한 것처럼 응용 프로그램에게 제공하는 핵심적인 추상화들에 대해 초점을 맞출 것이다.
8.2.1 Logical Control Flow
process는 프로그램들이 실제로는 system에서 동시적으로 실행되고 있음에도 불구하고, processor를 독점적으로 사용하고 있다는 환상을 보여준다.
Logical Control Flow란
- PC란 디버거를 통해 한 스텝씩 프로그램의 실행을 따라가면, 우리는 PC라는 값을 발견하게 될 텐데, 이는 program의 excecutable object file 또는 shared object들을 포함하는 instruction들이다.
- 이러한 일련의 PC값들을 logical control flow 라고 한다(간단하게 logical flow라고도 한다).
- 즉, 앞의 logical이라는 수식어가 붙은 것으로 유추해 볼 수 있듯이, 실제의 흐름이 아닌, 각 프로그램들이 자신만의 instruction들을 실행시키고 있는 것처럼 보이게 하는 흐름들을 logical control flow라고 한다.
- logical control flow가 있듯이 실제 instruction들이 실행되는 흐름을 physical control flow라고 하는데, 아래의 그림 8.12가 이 physical control flow를 보여주고 있다.
- 3개의 process가 실행되는 system을 고려해보자.
-
- key point
- 각 process는 하나의 physical control flow에서 일부분을 차지하고 있다.
- 각 프로세스는 flow의 일부를 실행한 다음, 다른 프로세스에 의해 선점되어 진다(preempted, 일시적으로 중단).
- key point
- 이러한 이유들로, 하나의 context에서 실행되는 프로그램 입장에서는 processor를 독점적으로 사용하는 것처럼 보인다.
- 이것을 어떻게 확인할 수 있는가? ⇒ 각 명령어의 elapsed time을 정확하게 측정한다면, CPU가 주기적으로 중지되는 것을 볼 수 있다.
8.2.2 Concurrent Flows
logical flow들은 computer system에서 다양한 형태를 가진다.
- exception handler
- processors
- signal handler
- threads
- java process
이 모든 것들이 logical flow의 예시이다. 그럼 concurrent flow는 어떤것인가?
Concurrent flows
어떤 실행이 다른 flow와 시간 상 겹치는 logical flow를 concurrent flow 라고 한다. 이 두 흐름은 동시에 실행된다고 할 수 있다.
- 더 정확하게는 X와 Y는 서로에 대해 아래와 같은 상황에서만 동시적(concurrent)하다고 할 수 있다.
- Y가 시작된 후, 그리고 Y가 끝나기 전에 X가 시작될 때,
- X가 시작된 후, 그리고 X가 끝나기 전에 Y가 시작될 때.
- 예: 8.12에서 A와 B, 그리고 A와 C는 동시적이다. 하지만 B와 C는 동시적이지 않다.
- 위 그림 8.12에서의 logical control flow가 전체 실행 흐름이라고 가정하고 있다. 이 때, B가 시작되고 끝나기까지 Process C는 시작도 하지 않았으므로 아무런 겹치는 것이 없다는 것이다.
- 즉, 착각하기 쉬운 점은 두개 이상의 logical flow가 같은 시점에서 동시에 실행 되는 경우 외에도, 번갈아 가며 실행되는 것을 시간 상 겹친다고 보고 있고, 이를 concurrent하다고 한다. 아래의 용어들을 알아보자.
여러 용어들
- multitasking
- concurrently하게 실행되는 여러 프름들을 concurrency라고 알고 있다.
- 이 때, multitasking은 프로세스가 다른 프로세스들과 교대로 실행된다는 개념이다.
- time slice
- 하나의 프로세스가 흐름 일부를 실행하는 매 시간을 time slice 라고 한다.
- 8.12에서의 A는 두개의 time slice로 구성된다고 할 수 있다.
- parallel flow
- 우선 concurrent flow는 processor 또는 computer의 core 수와는 무관하다.
- 그럼 core 수와 유관한 것은? → 바로 parallel flow이다.
- 여기서 우리가 집중해야 하는 것은, 동시성(concurrency)과 병렬성(parallelism)을 구분지어야 하는 것이다.
- parallel flow : concurrent flow의 부분집합으로써, 여러 core에 의해 각 flow들이 concurrently하게 실행된다면, 이건 parallel flow라고 한다.
8.2.3 Private Address Space
memory는 어떻게 독점적으로 사용하고 있는 것처럼 보이게 되는 걸까? 이것에 대해서 알아보자.
개요
- n-bit 주소 체계를 갖는 machine의 경우, 가능한 주소는 $2^n$개가 있다.
- process는 각 program마다 개인 고유의 private한 address space를 제공한다.
- 이런 private한 address space에 mapping된 memory 영역은 다른 process에서는 일반적으로 접근(read/write) 할 수 없다.
x86-64 Linux system의 private address space
- 가장 밑에는 code영역이다. 이는 항상 0x400000부터 시작한다.
- 가장 위에는 kernel space이다. kernel이 instruction들을 수행하기 위해 필요한 code, data, 그리고 stack 등이 있다.
User and kernel Modes
kernel이 완전히 차단된 process의 추상화를 위해 processor가 다른 응용프로그램의 address space에 접근할 수 있는 명령어들을 제한하는 매커니즘이 필요하다. 이 때 필요한 것이 user mode과 kernel mode이다.
- 이 매커니즘은 control register 안에 mode bit를 넣음으로써 구현이 되고 있다.x86 machine의 여러 control register.
- 즉, 이 mode bit는 process의 권한을 결정한다.
Kernel mode
- mode bit가 set 상태일 때 kernel mode, 또는 supervisor mode라고도 한다.
- system의 어느 memory 영역이던 간에 접근 가능
- 어느 instruction이던 간에 모두 실행이 가능하다.
user mode
- 특권이 필요한 instruction들은 실행 불가하다.
- 예) processor를 중지시키는 명령어
- 예2) mode bit를 바꾸게 하는 명령어
- 예3) I/O 작업
- process의 address space에서 kernel space에 있는 code와 data를 직접 참조하지 못한다.
- 이를 시도했을 시, 치명적인 protection fault가 발생한다.
- 이에, system call interface를 통해 trap을 거는 방식으로 간접 참조를 해야 한다.
어떻게 kernel mode로 바꾸는 걸까?
- Exception(Interrupt, Fault, Trapping system call)을 통한 방식이 유일하다.
- 과정
- exception이 발생한다.
- exception handler로 control 이 전달될 때, processor는 user에서 kernel mode로 바꾼다.(어떠한 명령어에 의해서).
- handler는 이에 따라 kernel mode에서 실행된다.
- handler가 application code로 반환될 때, processor는 다시 kernel에서 user mdoe로 바꾼다.
Linux에서의 kernel contents들을 보는 방법
- linux 운영체제에선 kernel contents들을 /proc 이라는 filesystem으로 확인할 수 있는 매커니즘을 제공한다.
- /proc filesystem
- 계층 구조를 갖는 text들이다.
- kernel의 많은 data structure들을 포함하고 있다.
- 예) /proc/cpuinfo 를 출력하면 cpu type에 대한 정보들을 출력해준다.
- 예2) /proc/{process_id}/maps 를 출력하면, 해당 process의 memory 영역들을 출력해준다.
- mac에서 이와 상응하는 명령어를 이용해 확인해본 결과
- vmmap {process_id} 를 출력한 결과
- /sys filesystem
- linux 2.6 버전 kernel에서는 더 low한 system bus 및 device관련해서 정보를 볼 수 있다.
8.2.5 Context Switches
OS kernel은 high level의 예외 로직을 이용해 multitasking을 구현하고 있다. 이 high level exceptional flow를 context switch라고 한다.
용어 정리
- Context
- 위에서 언급했다싶이, kernel이 process마다 유지하는, process의 실행에 필요한 모든 정보들을 포함한다.
- 왜 이러한 것이 필요한가? ⇒ 하나의 physical control flow에서 여러 logical control flow를 구현하기 위함이다.
- 즉, 이러한 context를 통해, 다른 process에 의해 중지되었던 process를 다시 재개할 때, 중지되기 전과 동일한 상황으로 실행할 수 있게 한다.
- 내용물 - general purpose register, floating-point register, PC, user’s stack, status register, kerner’s stack, kernel의 여러 자료구조들(page table, process-table, open file table)
- Scheduling
- kernel이 현재 선점 될 process를 고르고, 이전에 선점 당했던 process를 다시 재개하는 하는 이러한 결정을 scheduling이라고 한다.
- Scheduler
- 위 scheduling은 kernel에 있는 code에 의해 실행되는데, 이러한 code를 scheduler라고 한다.
Context Switch가 발생하는 예
- kernel이 현재 process(user program)을 대신해서 system call을 실행할 때
- system call이 어떠한 event를 기다리기 위해 block 되었다면, kernel은 현재 process를 sleep으로 두고, 다른 process로 switch한다.
- 예) read system call은 disk access를 요청 → kernel은 disk로부터 data가 도착하기까지 기다리는 것 대신에 context switch를 통해 다른 process를 실행한다.
- 보통 kernel은 system call이 block되지 않는다고 하더라도, 현재 process에 control을 반환하는 것 대신에 context switch를 수행할 수도 있다.
- sleep system call을 명시적으로 호출할 때
- system call이 어떠한 event를 기다리기 위해 block 되었다면, kernel은 현재 process를 sleep으로 두고, 다른 process로 switch한다.
- Interrupt가 발생할 때
- 모든 system에선 주기적으로 timer interrupt를 발생시키는 매커니즘이 있다. 보통은 1ms ~ 10ms정도 된다.
- 이런 timer interrupt가 발생할 때마다 kernel은 현재 process가 충분히 길게 실행되었다고 판단하고, context switch를 통해 새 process로 전환한다.
- 모든 system에선 주기적으로 timer interrupt를 발생시키는 매커니즘이 있다. 보통은 1ms ~ 10ms정도 된다.
Context Swiching 기법의 과정
- context switch 전
- kernel이 Process A의 user mode에 있는 명령어들을 실행한다.
- switch의 첫 부분
- kernel이 A를 대신하는, kernel mode에 있는 instruction을 수행
- some point
- kernel이 B를 대신하는, kernel mode의 instruction을 수행
- switch 이후
- kernel이 B를 대신하는, user mode에 있는 instruction을 수행
'Computer Science > 컴퓨터 구조' 카테고리의 다른 글
[CSAPP] 9.8 Memory Mapping (메모리 맵핑) (0) | 2023.03.01 |
---|---|
[CSAPP] 8.3 System Call Error Handling (시스템 콜 에러 처리) (0) | 2023.03.01 |
[CSAPP] 9.3 VM as a Tool for Caching(캐싱 도구로서의 VM) (0) | 2023.03.01 |
[CSAPP] 9.2 Address Spaces(주소 공간) (0) | 2023.03.01 |
[CSAPP] 9.1 Physical and Virtual Addressing(물리 및 가상주소 방식) (0) | 2023.03.01 |