| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- Binary Lifting
- DP
- Behavior Design Pattern
- 강한 연결 요소
- ccw 알고리즘
- Github
- localstorage
- 트라이
- trie
- 분리 집합
- LCA
- 2-SAT
- 벨만-포드
- 게임 서버 아키텍처
- R 그래프
- Spin Lock
- 비트마스킹
- PROJECT
- 최소 공통 조상
- 이분 탐색
- SCC
- map
- MongoDB
- 비트필드를 이용한 dp
- 자바스크립트
- Express.js
- Strongly Connected Component
- 그래프 탐색
- JavaScript
- Prisma
Archives
- Today
- Total
dh_0e
[OS] Process, Context Switch 본문
Scope of OS(운영체제의 범위)
- 프로세스 관리(Process Management)
- 메모리 관리(Memory Management)
- 파일 관리(File Management)
- I/O 시스템 관리(I/O System Management)
- 네트워킹(Networking)
- 보안(Security)

컴파일러(Compiler)
- 역할
- 사람이 이해할 수 있는 프로그래밍 언어로 작성된 Source Code를 컴퓨터(CPU)가 이해할 수 있는 기계어로 표현된 Object 파일로 변환
- x86 vs ARM vs RISC-V 등 다양한 명령어 셋에 따라 Object 파일의 형태가 달라질 수 있음
- Object file: 컴퓨터가 이해할 수 있는 기계어로 구성된 파일
- 자체로는 수행이 이루어지지 못함
- 프로세스로 변환되기 위한 정보가 삽입되어야 함 (헤더, 텍스트 섹션, 데이터 섹션, 주소 정보 변환 등)
- Relocatable Addresses(Relative Address: 상대 주소)로 표현
- 심볼들의 주소가 상대적인 값으로 표현됨 (ex. 시작 주소로부터 26바이트 지점)
- 사람이 이해할 수 있는 프로그래밍 언어로 작성된 Source Code를 컴퓨터(CPU)가 이해할 수 있는 기계어로 표현된 Object 파일로 변환

링커(Linker)
- 역할
- 관련된 여러 Object 파일들과 라이브러리들을 연결하여, 메모리로 로드될 수 있는 하나의 Executable 파일로 변환
- Executable File: 특정한 환경(OS)에서 수행될 수 있는 파일
- 프로세스로의 변환을 위한 Header, 실제 작업 내용인 Text, 필요한 데이터인 Data를 포함
- Absolute Addresses(절대 주소)로 표현됨
- 심볼들의 주소가 절댓값으로 표현됨 (ex. 32026번 주소)
- ex) exe file
- 컴파일러와 링커는 결과물이 수행될 OS와 CPU에 따라 다른 형태의 파일을 만듦
로더(Loader)
- 역할
- Executable 파일을 실제 메모리에 올려주는 역할을 담당하는 OS의 일부
- Loading: RAM에 올려서 실행할 준비를 끝내고, 프로세스로서 존재하게 만드는 것
- 동작 과정
- Executable의 Header를 읽어, Text와 Data의 크기 결정
- 프로그램을 위한 가상 메모리 공간인 Address Space를 생성
- Text와 Data들을 방금 생성한 Address Sapce로 복사
- 프로그램이 실행될 때 필요한 추가적인 정보들(Argument)은 Stack 메모리 영역에 복사
- CPU 내 임시 저장 공간인 Register를 초기화하고,
프로그램의 시작 지점(Start-up Routine)으로 Jump 해서
첫 번째 명령어(PC)를 실행하도록 지시
런타임 시스템(Runtime System)
- 역할
- 응용 프로그램의 효율적인 실행을 지원하기 위해 프로그램과 연결하여 상호 작용함
- C Runtime System Program Execution
- 자동 준비 코드 추가: GCC(GNU Compiler Collection)는 Start-up Code Object(준비 코드) 파일을 추가하여 런타임 시스템 프로그램을 컴파일하며, 이때 기본 라이브러리들도 동적으로 링크됨
- 첫걸음 지시: 프로그램이 시작될 때, CPU의 PC에게 "자, 이제 _start(공식 시작점)라는 곳으로 가서 첫 번째 명령을 실행해!"라고 지시함
- 초기화 작업: _start 함수는 바로 main()을 호출하지 않고, 먼저 _libc_start_main을 호출하여 C 라이브러리 및 스레드 환경을 초기화함
- 초기화 이후, 프로그램의 $main()$ 함수가 호출됨


프로세스 (Process)
- Execution Unit(실행 단위): OS가 여러 프로그램을 번갈아 가면서 실행시킬 때(스케줄링)의 단위
- Protection Domain(보호 영역): 각 프로세스는 독립적인 공간을 가져, 서로 영역을 침범하지 못함
| 구성 요소 | 설명 |
| Program Counter (PC) | CPU 레지스터 중 하나로, 다음에 실행할 명령어의 주소를 가리킴 |
| Stack | 함수 호출 정보(리턴 주소, 매개변수), 지역 변수 저장. 함수 호출 시 쌓이고(return 시 사라짐) |
| Heap | malloc, new 같은 동적 메모리 할당 영역 |
| Data Section (.data) | 초기화된 전역 변수, 정적 변수 저장 |
| BSS Section (.bss) | 초기화되지 않은 전역/정적 변수 저장 |
| Text Section (.text) | 프로그램의 기계어 코드(명령어) 저장 |
프로세스는 디스크에 저장된 프로그램으로부터 변환되어 메모리로 로딩된다.
(하드디스크에 그냥 파일로 누워 있던 프로그램이 실행 버튼을 누르는 순간, 운영체제가 그 내용을 메모리(RAM)로 가져와서 ‘살아 있는 작업(프로세스)’으로 만들어 준다.)


프로세스 상태(Process State)
- 대표적 States
- New: 프로세스가 생성되고 있는 상태
- Ready: 프로세서 할당을 기다리는 상태
- Running: 명령어들이 실행되고 있는 상태
- Waiting: I/O 완료, 신호 수신과 같은 어떠한 이벤트 발생을 기다리는 상태
- Terminated: 프로세스 실행이 완료된 상태
- 커널 내에 Ready Queue, Waiting Queue, Running Queue를 두고 프로세스들을 상태에 따라 관리함
- Ready Queue: CPU(프로세서)를 기다리는 프로세스들이 할당을 기다리며 줄 서 있는 곳
- Waiting Queue: 어떤 이벤트가 발생하기를 기다리는 프로세스들이 모여있는 곳
- Running Queue: 현재 CPU에서 실행 중인 프로세스 (현재 실행 중인 프로세스 자체를 의미)

- New → Ready: admitted - 새로운 프로세스가 시스템에 추가될 준비가 됨
- Ready → Running: scheduler dispatch - 스케줄러가 Ready 상태의 프로세스에게 CPU를 할당함
- Running → Ready: timer interrupt - 할당된 시간이 다 되거나 더 높은 우선순위의 프로세스가 나타나 CPU를 선점당함
- Running Waiting: I/O or event wait - 프로세스가 I/O 작업 완료 또는 특정 이벤트 발생을 기다림
- Waiting Ready: I/O or event completion - 기다리던 I/O 작업 또는 이벤트가 완료됨
- Running Terminated: exit - 프로세스 실행이 완료됨

- enum procstate: 프로세스의 가능한 상태를 정의합니다.
- UNUSED: 사용되지 않음.
- EMBRYO: 생성 중인 초기 상태.
- SLEEPING: 어떤 이벤트를 기다리며 잠들어 있는 상태.
- RUNNABLE: 실행 준비 완료 상태 (Ready).
- RUNNING: 현재 실행 중인 상태.
- ZOMBIE: 실행은 종료되었지만 부모 프로세스가 아직 수확(cleanup)하지 않은 상태.
- struct proc: 각 프로세스에 대한 정보를 담는 구조체 (프로세스 제어 블록, PCB).
- uint sz: 프로세스 메모리 크기 (바이트).
- pde_t* pgdir: 페이지 테이블 (가상 메모리 관리).
- char *kstack: 커널 스택의 바닥 주소. (마지막 주소: kstack-stack_start=stack_size)
- enum procstate state: 현재 프로세스 상태.
- int pid: 프로세스 ID.
- struct proc *parent: 부모 프로세스 포인터.
- struct trapframe *tf: 현재 시스템 호출을 위한 트랩 프레임.
- struct context *context: 프로세스를 실행하기 위한 컨텍스트 (swtch()에 사용).
- void *chan: (Non-zero일 경우) 어떤 채널에서 잠들어 있는지.
- int killed: (Non-zero일 경우) 종료 명령을 받았는지.
- struct file *ofile[NOFILE]: 열린 파일 목록.
- struct inode *cwd: 현재 작업 디렉토리.
- char name[16]: 프로세스 이름 (디버깅용).
프로세스 제어 블록(Process Control Block)
- 각 프로세스는 OS에서 PCB로 표현됨

- 각 프로세스와 관련된 정보
- Process State: 프로세스의 현재 상태
- Program Counter: 다음에 실행할 명령어 주소
- CPU Registers: 프로세스가 실행될 때 CPU 레지스터에 저장된 값들
- accumulator, index registers, stack pointers 등
- CPU Scheduling Information: 프로세스 우선순위, 스케줄 큐 포인터 등
- Memory Management Information: 페이지 테이블 또는 세그먼트 테이블, 메모리 제한 레지스터 값 등
- Accounting Information: CPU 사용 시간, 실제 사용 시간, 시간제한, 프로세스 번호 등
- I/O Status Information: 프로세스에 할당된 I/O 장치 목록, 열린 파일 목록 등
문맥 전환(Context Switch)
- CPU가 새로운 프로세스로 전환될 때, 커널이 기존(현재) 프로세스의 상태를 저장하고, 새로운 프로세스를 위해 저장된 상태를 로드하는 과정
- Overhead: Context Switching 하는 시간
- 시스템은 전환하는 동안 유용한 작업을 수행하지 못함
- Context Switching 시간은 하드웨어 지원에 따라 달라짐

프로세서 구조에 따른 Context Switch의 차이
CISC(Complex Instruction Set Computer)
- 복잡한 명령어 셋 구성: 효율을 높이지만, 클럭 속도가 저하될 수 있음
- 클럭 속도: 프로세서의 작동 속도, CPU가 명령어를 처리하는 빠르기를 결정하는 요소
- 복잡한 회로: 물리적인 공간을 많이 차지하고, 레지스터 용량이 저하될 수 있음 (레지스터 적음)
- ex) Intel Pentinum Processor
RISC(Reduced Instruction Set Computer)
- 간단한 명령어 셋 구성: 클럭 속도가 높고, 빠른 수행 속도를 가짐
- 절약된 물리적 공간: 더 많은 레지스터를 장착할 수 있음 (레지스터 많음)
- ex) ARM Processor
- Register Window(Berkely RISC Design): Context Switch 오버헤드를 줄이기 위한 방법 중 하나
| 구분 | CISC (Complex Instruction Set Computer) | RISC (Reduced Instruction Set Computer) |
| 설계 철학 | 복잡한 일을 한 명령어로 처리 | 단순한 명령어를 빠르게 많이 처리 |
| 명령어 수 | 많음, 형식도 다양 | 적음, 형식이 규칙적·단순 |
| 명령어 길이 | 가변 길이 (1바이트 ~ 여러 바이트) | 대부분 고정 길이 (예: 32비트) |
| 수행 사이클 | 한 명령어가 여러 클럭 사이클 사용 | 한 명령어당 1클럭이 목표 (파이프라인에 유리) |
| 주소 지정 방식 | 매우 다양, 복잡한 주소 지정 지원 | 주소 지정 방식이 제한적·단순 |
| 하드웨어 복잡도 | 디코더·마이크로코드 등 하드웨어 복잡 | 하드웨어 단순, 대신 컴파일러 최적화 중요 |
| 코드 길이 | 한 명령어가 많은 일을 해서 상대적으로 짧을 수 있음 | 같은 일을 하려면 명령어 개수가 더 많아져 길어질 수 있음 |
| 파이프라이닝 | 복잡한 명령어 때문에 파이프라인 설계가 어려울 수 있음 | 규칙적인 명령어 덕분에 파이프라인·슈퍼스칼라에 유리 |
| 대표 예시 | x86, x86-64 (인텔, AMD CPU) | ARM, MIPS, RISC-V, PowerPC 등 |
CISC는 하나의 복잡한 명령어를 처리하는 데 많은 시간이 걸리지만, RISC는 단순한 명령어를 빠르게 처리하여 전반적인 효율을 높임
문맥 전환 측면에서는 RISC가 더 많은 레지스터를 가질 수 있어 효율적일 수 있지만, 그만큼 전환 시 저장/복원해야 할 데이터가 많아질 수 있다는 점이 특징
비유
RISC: “칼, 망치, 드라이버”처럼 도구는 단순하지만 빠름
CISC: “만능 공구”처럼 한 번에 여러 기능 가능하지만 무겁고 느림
프로세스 생성(Process Creation)
- 시스템 내의 프로세스들은 동시에 실행될 수 있으며, 동적으로 생성/종료될 수 있음
- OS는 프로세스 생성 및 프로세스 종료 메커니즘을 제공함
- fork(): 유닉스/리눅스 시스템에서 새로운 프로세스를 만드는 가장 대표적인 방법
- Parent process vs Child process
- 원래 실행되고 있던 프로세스가 '부모'가 되고, 새롭게 생성된 프로세스가 '자식'이 됨
- 자식 프로세스는 부모 프로세스를 거의 그대로 복사해서 만들어짐
- Resource Sharing(자원 공유)
- 부모와 자식이 모든 자원을 공유(default)
- 자식이 부모 자원의 일부만 공유받음
- 부모와 자식이 아무 자원도 공유하지 않음
- Execution(실행 방식)
- 부모와 자식이 동시에 실행됨
- 부모가 자식이 종료될 때까지 기다림
- Parent process vs Child process
Process Creation in Memory View
- 메모리(Text 및 Data 섹션)
- 자식 프로세스는 부모 프로세스의 복제본임
- 자식 프로세스에 프로그램이 로드됨
- in Unix
- fork() 시스템 호출로 새로운 프로세스가 생성
- 새로운(자식) 프로세스는 원본(부모) 프로세스의 메모리를 복사한 것으로 구성됨
- exec(2): 새로운 프로그램으로 메모리를 교체
- 자식 프로세스는 부모와 똑같은 코드를 가지고 있지만, 대부분의 경우 exec()를 호출하여 자신만의 새로운 프로그램의 코드를 메모리에 로드하고 기존의 부모 코드를 지움
- 완전히 새로운 프로그램을 실행하는 부모와 별개의 프로세스로 거듭남
- fork() 시스템 호출로 새로운 프로세스가 생성

- fork()와 exec()는 자주 함께 사용되어 새로운 프로그램을 실행하는 과정을 만듦
- fork()로 공간을 만들고, exec()로 그 공간에 새로운 프로그램을 채워 넣는 식
Process Creation in UNIX


- ※ execl이 성공하면 그 시점에서 "지금 돌고 있던 프로그램"이 통째로 사라지고 /bin/ls 프로그램으로 갈아 끼워지기 때문에, 그 아래에 있는 for문, 맨 밑에 wait도 절대 실행되지 않음
- 현재 프로세스(자식)의 메모리 공간(코드, 데이터, 힙, 스택)을 전부 버리고 새로운 실행 파일(/bin/ls)을 그 자리에 로드
- 프로세스 ID(pID)는 유지되지만, "프로그램"은 완전히 다른 것으로 바뀜
- 새 프로그램의 시작점(main 함수)부터 다시 실행을 시작
- OS 입장에서 단계별
- 자식이 execl 시스템 콜을 호출
- 커널이 /bin/ls 실행 파일을 찾아서 ELF 헤더 같은 걸 확인
- 기존 자식 프로세스의 사용자 영역(code, data, stack 등)을 전부 제거
- /bin/ls의 코드와 데이터로 새 주소 공간을 구성
- 레지스터, 스택 등을 새 프로그램의 시작 상태로 세팅
- 이제부터 이 프로세스는 “ls 프로세스”가 됨. main(int argc, char **argv) 같은 곳부터 실행 시작
Process Creation in XV6

프로세스 종료(Process Termination)
- 프로세스는 최종 명령문을 실행하고 운영체제에 삭제를 요청하기 위해 exit 시스템 호출을 사용하여 종료됨
- 부모에게 return: 자식의 출력 데이터는 wait를 통해 부모에게 전달될 수 있음
- OS의 할당 해제: 프로세스의 자원은 OS에 의해 할당 해제됨
- abort 함수: 비정상적인 프로세스 종료를 유발
- 호출 프로세스에게 SIGABRT시그널을 전송
- Core dump 발생
'Operating System' 카테고리의 다른 글
| [OS] CPU Scheduling (1) | 2025.11.10 |
|---|---|
| [OS] Basic H/W Mechanisms (Bus, I/O Event, Handling and Device Access Mechanisms) (0) | 2025.11.08 |
| [OS] Operating System Structure, Kernel Designs (Monolithic, Micro, Hypervisor) (0) | 2025.11.03 |
| [OS] Operating System (0) | 2025.10.01 |
| [OS] Introduction to OS (0) | 2025.09.30 |