일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- Deep Learning
- concurrency
- 프로그래밍
- 7월4일
- 영어논문
- list
- CLRS
- Lock
- control flow
- 직업으로서의 정치 서평
- 독립기념일
- Process
- 푸드트럭
- Snap!
- insertion Sort
- 코딩
- 스크래치
- Scratch
- 균형의 정치
- 운영체제 강의
- The beauty and Joy of computing
- xv6
- 미국
- 맛집
- 여행
- Operating System
- 버클리
- 잘 짜인 코드
- scheduling policy
- Jupyter Notebook
- Today
- Total
여행다니는 펭귄
Process 란 무엇일까? 본문
1. Hardware
2. C code to Process
3. Process
1. Hardware
Intel x86 Processor
Architecture
Programmer's View
왜 Operating System에 대해서 공부하는데 하드웨어에 대해 알아야 하냐구요?
프로세스랑 CPU랑 무슨 상관이라고 왜 갑자기 하드웨어에 대해 이야기 하는지 이해가 잘 안가실 텐데요

모든 프로그램은 그 하드웨어의 특성과 구조에 영향을 받거든요. 고로 하드웨어에 대한 기본적인 이해는 있어야 한다. 이정도 알아두시고 대충 읽고 넘어가주세요.
Intel x86 Processor
laptop/desktop/server에서는 거의 독점적인 위치를 가지고 있으므로, 위 Cpu를 기준으로 소개하도록 하겠습니다.
혹시 임베디드 OS에 관심이 있으시다면 ARM Processor에 대해 알아보시는 것을 추천해요.
ARM 아키텍처 - 위키백과, 우리 모두의 백과사전 (wikipedia.org)
ARM 아키텍처 - 위키백과, 우리 모두의 백과사전
64/32비트 아키텍처발표2011년 (10년 전)(2011)버전Armv8-A, Armv8.1-A, Armv8.2-A, Armv8.3-A, Armv8.4-A, Armv8.5-A, Armv8.6-A인코딩AArch64/A64 및 AArch32/A32는 32비트 명령어를 사용하며, T32(Thumb-2)는 혼재된 16비트, 32비트
ko.wikipedia.org
아무튼 Intel Processor은 CISC 구조를 가지고 있답니다.
CISC 란?
Complex Instruction Set Computer을 의미하며, 많은 different하고 complex한 instruction set을 제공합니다.
이에 반대되는 CPU Structure은 RISC(=Reduced Instruction Set Computer) 이며, 기능이 적은 대신 Performance가 매우 뛰어나다고 할 수 있죠 :)
현재 사용하고 있는 방식은 그 완전한 CISC도 아니고 RISC도 아닌 짬뽕이라고 할 수 있어요.
Architecture
Architecture가 뭘까요?
많이들 들어보셨을 거에요 인텔의 새 cpu 아키텍쳐가 어쩌구
Architecture란 정확하게 말하면 프로세서 디자인의 일부로, 어셈블리 코드를 이해할때 사용하는 부분이랍니다. 다른 말로는 ISA (Instruction Set Architecture) 라고도 불리죠. (Intel에는 x86과 IA32 가 있어요)
마이크로 아키텍쳐는, 아키텍쳐를 실물로 구현한 것을 의미합니다.
Programmer's View
제가 하드웨어에 대해서 소개는 하지만 저희가 그 실리콘이 뭐가들어가는지 공정 과정이 어떤지는 사실 알 필요 없어요.
이걸 다 알고 프로그램을 짜야 한다면 효율이 너무 떨어지겠죠?
이 CPU 구조를 Programmer's Perspective에 맞춰서 Abstraction 해야 한답니다.
그럼 Programmer - Visible State에는 뭐가 있을까요?
CPU | Memory | |
PC (Program Counter) |
Address of next instruction Called “EIP” (IA32) or “RIP” (x86-64) |
Byte addressable array Code, user data, (some) OS data Includes stack used to support procedures |
Register file | Heavily used program data | |
Condition Codes | Store status information about most recent arithmetic operation Used for conditional branching |
다만 Memory 구조를 어떻게 보느냐 이 부분에 대해서는 여러 연구가 이루어지고 있어서
폰 노이만 구조와 하버드 구조
Von Neumann architecture. 존 폰노이만이 제시한 컴퓨터 구조. 프로그램 내장 방식이라고도 불립니다. 그 이전의 컴퓨터들은 스위치를 설치하고 전선을 연결하여 데이터를 전송하고 신호를 처리하는
velog.io
를 참조하시는 걸 추천드려요.
일단 추후 읽으실 모든 글들은 폰 노이만 구조를 기준으로 되어 있으니 참고 부탁드립니다.
여기까지 프로그래머가 봐야 하는 Processor에 대한 설명은 이만 마치고, C 언어가 프로그램, 그리고 프로세스가 되는 과정에 대해서 알아보도록 할게요.
2. C code to Process
Turning C into Object Code
Executable Object File Formet (ELF Format) (binary files)
Linking
Load
Turning C into Object Code
다들 c 언어로 Compile을 해보셨을거에요.
gcc -O1 main.c sum.c -o p
이는 컴파일 최적화 옵션을 1단계로 주고, p라는 실행 파일을 만들라는 의미입니다.
이게 구체적으로 어떻게 실행이 되는지 한번 볼까요?
text : C program (main.c sum.c) |
↓ Compiler( gcc - S ) |
text : Assembly program (main.s sum.s) |
↓ Assembler (gcc –c or as) |
binary : Object program (main.o sum.o) |
↓ Linker (gcc or ld) |
binary : Executable program (p) ← Static libraries (.a) |
이제 실행가능한 Binary file을 만들었으니 이것이 어떻게 저장되어 있는지 봅시다.
Executable Object File Formet (ELF Format) (binary files)
실행 파일은 어떻게 저장이 되어 있을까요?
Byte ordering, file type (.o, exec, .so), machine type (e.g., IA32), etc Page size, virtual addresses memory segments (sections), segment sizes |
ELF header |
Segement header file (required for excutables) |
|
Code | .text section |
Read only data: jump tables for switch, … (const int a = 10;) | .rodata section |
Initialized global variables ( int a = 10; ) | .data section |
Uninitialized global variables ( int a; ) Holds variables that don't have any value yet Occupies no space |
.bss section |
.symtab section | |
.rel .txt section | |
.rel .data section | |
.debug section | |
section header table |
와 같이 HDD, SDD 같은 저장 장치에 올라가 있답니다.
Linking
생각해보니 main.o와 sum.o가 어떻게 p라는 하나의 파일로 합쳐질 수 있을까요?
사실 main.o 와 sum.o는 완벽한 실행 파일이 아니라 Relocatable Object Files 라고 불리는 불완전한 실행 파일입니다.
Relocatable Object Files | ELF | ||||
System Code | .text | Headers | . text | ||
System data | .data | System code | |||
main() | |||||
sum() | |||||
main.o | main() | .text | more system code | ||
int buf[2] = {1,2} | .data | ||||
static int t | |||||
sytem data | data | ||||
int buf[2] = {1,2} | |||||
sum. o | sum() | . text | static int t | bss | |
.symtab .debug |
Relocatable Object Files 들이 System Code와 System data로 나뉘어져 하나의 ELF 파일로 들어가게 되어. p 라는 File이 생기게 되는 것이죠.
Load
그럼 이 파일(p) 를 실행하면 어떻게 될까요?
일단 Disk에 저장되어 있던 ELF 파일이 메모리에 위와 같이 Load 되게 됩니다. 이 과정까지 마치면 p라는 파일이 이제 Process 가 되게 되는 것이죠.
Kernel virtual memory | ← %esp ← brk > Loaded from ELF |
User stack (created at runtime) |
|
↓ ↑ |
|
Run-time heap (created by malloc) |
|
Read/write segment (.data, .bss) |
|
Read-only segment (.init, .text, .rodata) |
이렇게 하여 C Code File 이 Process 가 되는 과정에 대해 알아보았습니다.
이제 이 Process 란 무엇인지 알아보도록 합시다 :>
3. Process
Process
Running Process
Process
Process라고 하는 것은 Logical control flow(: 제어 흐름)라는 개념과, Private virtual adress space(: 독립된 메모리 공간)라는 두개의 중요한 Abstraction이 동반되어야 합니다.
OS에서 Process를 제어하고 상태를 알아보기 위해 제공되는 Process APIs가 있고, 이에 대한 사용법은 운영체제에서는 다루지는 않으나, 대략 Overview 정도만 하도록 하겠습니다.
These APIs are available on any modern OS
Create: Create a new process to run a program
e.g., fork() and execv()
Destroy: Halt a runaway process
e.g., exit() and kill(SIGKILL)
Wait: Wait for a process to stop running
e.g., wait() and waitpid()
Miscellaneous Control: Some kind of method to suspend a process and then resume it
e.g., kill(SIGSTOP) and signal()
Status: Get some status info about a process
e.g., getpid(), getpriority(), …
Running Process
그 전 글에서 간단하게 fetch, execute, decode를 통해서 process의 실행 절차를 보여드리긴 했으나 구체적으로 보여드리지는 않았습니다. 이제 구체적으로 한번 살펴볼까요?
1. 프로그램을 메모리로 로드하고, Process가 되면 그에 상응하는 Adress Space를 생성한다.
프로그램은 Disk 공간에 저장되어 있는 상태입니다.
OS는 이를 메모리로 로딩하고 이 로드된 code와 data가 프로그램이 실행되는 중에 계속해서 샤옹됩니다.
2. 프로그램의 run-time stack 을 할당해준다.
Local Variable, Function Parameter, Return Adress를 저장하기 위해 Stack이 사용됩니다.
인수로 Stack을 초기화 하기도 합니다. (argc and argv array of main() function)
3. 프로그램의 Heap 이 생성된다.
heap은 dynamically allocated data를 위해서 사용하는 공간입니다.
malloc()을 통해서 heap 공간을 잡게 되고 free()로 점유 공간을 다시 해제합니다.
4. OS가 다른 Initialization 작업들을 진행한다.
I/O(Input Output) step
Process 마다 세개의 파일을 기본적으로 열게 되는데 (Stdin Stdout Stderr) 이를 열어줍니다.
5. 엔트리 포인트에서 프로그램을 실행한다. main()
OS가 CPU에게 process의 control flow를 전송합니다.
그런데 우린 어떻게 CPU도 한개고 메모리도 한정이 되어 있는데 Logical control flow라는 개념과, Private virtual adress space 을 여러개의 동시실행되는 Process에게 모두 줄 수 있을까요?
이를 다음 글에서 알아보도록 하겠습니다
'컴퓨터 > 운영체제' 카테고리의 다른 글
Concurrency는 뭘까요? (0) | 2021.10.17 |
---|---|
Scheduling Policy는 어떻게 짜야 할까요? (0) | 2021.10.17 |
왜 Direct Execution을 하지 않을까? (0) | 2021.10.08 |
Operating System 이란? (0) | 2021.09.28 |
Operating System : 운영체제 (0) | 2021.09.27 |