응용 프로그램 → 운영체제 → 하드웨어 순으로 동작하며, 이 과정에서 운영체제가 하드웨어와의 직접적인 인터페이스를 담당한다.
┌───────────────────────┐
│ 응용 프로그램 (App) │ ← 사용자가 직접 실행 (ex: 게임, 웹브라우저, DB)
└───────────────────────┘
⬇
┌───────────────────────┐
│ 운영체제 (OS) │ ← 응용 프로그램과 하드웨어 사이의 인터페이스
│ - 시스템 콜 (System Call) │
│ - 드라이버 (Device Driver) │
└───────────────────────┘
⬇
┌───────────────────────┐
│ 하드웨어 (Hardware) │ ← CPU, 메모리, 디스크, 네트워크 등
└───────────────────────┘
- 응용 프로그램이 운영체제에게 서비스를 요청하는 인터페이스
- 응용 프로그램이 직접 하드웨어를 다룰 수 없으므로, 운영체제에 특정 기능을 요청해야 한다.
이를 위해 제공되는 기능이 시스템 콜(System Call) 이다.
응용 프로그램 (텍스트 편집기) → 시스템 콜 open() 요청 → 운영체제 → 하드웨어에서 파일 읽기
운영체제에서 제공하는 주요 시스템 콜
파일 처리: open(), read(), write(), close()
프로세스 관리: fork(), exec(), wait()
메모리 관리: malloc(), mmap()
네트워크 처리: socket(), connect()
입출력(IO): ioctl()
역할
- 운영체제가 하드웨어를 제어하기 위해 제공하는 소프트웨어
- 운영체제는 하드웨어마다 적절한 드라이버를 로드하여 해당 장치를 제어한다.
1. USB를 컴퓨터에 연결
2. 운영체제가 USB 드라이버 로드
3. 응용 프로그램에서 USB 파일을 읽기 요청
4. 운영체제가 드라이버를 통해 USB 장치와 통신
5. 파일을 응용 프로그램에 전달
- 운영체제의 핵심 부분으로, 하드웨어와 직접 상호작용하는 역할
- 커널(Kernel)은 운영체제의 핵심이며, 모든 하드웨어 리소스를 관리한다.
- 응용 프로그램이 요청하면 커널이 시스템 콜을 통해 하드웨어에 명령을 전달한다.
역할
응용 프로그램이 파일을 읽는 과정
1. 응용 프로그램: "파일을 읽어야 해!" → `open("data.txt")` 실행
2. 운영체제 (커널): 시스템 콜(`open()`)을 통해 요청 확인
3. 운영체제: 파일 시스템 드라이버를 통해 HDD/SSD에서 "data.txt" 파일 검색
4. 하드웨어: HDD/SSD에서 해당 파일의 데이터를 RAM으로 로드
5. 운영체제: 응용 프로그램에 파일 내용을 반환
캐보드 입력이 응용 프로그램에 전달 되는 과정
1. 사용자가 키보드에서 "A" 입력
2. 키보드 드라이버가 인터럽트 발생 (하드웨어 → 운영체제)
3. 운영체제는 키 입력을 처리하고, 해당 데이터를 응용 프로그램에 전달
4. 응용 프로그램(텍스트 편집기)이 "A"를 화면에 출력
💡 커널은 운영체제의 핵심이며, 하드웨어와 직접 상호작용하는 역할
👉 커널을 수정하면 프로세스 관리, 파일 시스템, 메모리 관리, 입출력(IO) 방식 등을 변경할 수 있다.
📌 커널 수정 예시
💡 드라이버는 운영체제가 하드웨어를 조작하는 중간 다리 역할
👉 드라이버를 수정하면, 키보드, 마우스, GPU, 네트워크 장치 등의 동작을 변경할 수 있다.
📌 드라이버 수정 예시
💡 시스템 콜은 응용 프로그램이 운영체제에게 특정 기능을 요청하는 인터페이스
👉 시스템 콜을 수정하면 응용 프로그램이 하드웨어를 다루는 방식을 변경할 수 있다.
📌 시스템 콜 수정 예시
프로세스(Process) 는 실행 중인 프로그램(Executable Code + 실행 상태) 을 의미한다.
즉, 하드디스크나 SSD에 저장된 프로그램 파일이 운영체제(OS)에 의해 메모리(RAM)로 로드되어 실행되는 개체를 프로세스라고 한다.
✅ 독립적인 실행 단위
✅ 운영체제에 의해 관리됨
✅ 멀티태스킹 지원
✅ 동기 & 비동기 실행 가능

프로그램은 실행되기 전의 코드 파일이고, 프로세스는 실제로 실행되고 있는 개체이다.
[New] → [Ready] → [Running] → [Waiting] → [Terminated]

프로세스는 CPU를 사용하기 위해 Ready → Running 상태로 전환되며, 실행 중에 I/O 요청이 발생하면 Waiting 상태로 이동한다.
┌─────────────────┐
│ Stack (스택) │ 지역 변수, 함수 호출 정보 (LIFO 구조)
├─────────────────┤
│ Heap (힙) │ 동적 메모리 할당 (`malloc()`, `new`)
├─────────────────┤
│ Data (데이터) │ 전역 변수, static 변수 저장
├─────────────────┤
│ Code (코드) │ 실행할 프로그램의 코드 (CPU 명령어)
└─────────────────┘
✅ Stack (스택): 함수 호출 시 생성되는 지역 변수 저장
✅ Heap (힙): 실행 중 동적으로 할당되는 메모리 영역
✅ Data (데이터): 프로그램이 사용하는 전역 변수 저장
✅ Code (코드): 실행 파일의 명령어(코드)가 저장됨
👉 이처럼 프로세스마다 독립적인 메모리 공간을 가지기 때문에, 한 프로세스가 다른 프로세스의 메모리를 직접 수정할 수 없다.
👉 프로세스 간 데이터를 주고받으려면 IPC(Inter-Process Communication) 기법을 사용해야 한다.
운영체제는 여러 프로세스를 동시에 실행할 수 있도록 CPU 스케줄러를 사용하여 프로세스를 관리한다.
✅ 선점형 스케줄링 (Preemptive Scheduling)
한 프로세스가 실행 중이어도, 운영체제가 강제로 CPU를 빼앗아 다른 프로세스에 할당할 수 있음.
Round Robin, Priority Scheduling, Multilevel Queue 방식이 있음.
✅ 비선점형 스케줄링 (Non-Preemptive Scheduling)
한 프로세스가 실행을 마칠 때까지 CPU를 유지함.
FCFS (First Come First Serve), SJF (Shortest Job First) 방식이 있음.
👉 운영체제는 CPU 시간을 효율적으로 배분하여, 여러 프로세스가 동시에 실행될 수 있도록 한다.
프로세스는 각각 독립적인 메모리 공간을 가지므로, 데이터를 공유하려면 스 간 통신) 방법을 사용해야 한다.

프로세스 간 통신(IPC, Inter-Process Communication) 의 흐름은 다음과 같이 진행된다.
즉, 한 프로세스가 데이터를 생성하고, 이를 운영체제를 통해 다른 프로세스로 전달하는 과정이 포함된다.
┌───────────────┐ ┌───────────────┐
│ Process A (Sender) │ → │ Process B (Receiver) │
│ (데이터 생성) │ │ (데이터 수신) │
└───────────────┘ └───────────────┘
↘ ↙
운영체제(OS) → (데이터 관리)
📌 기본적인 흐름
1️⃣ 프로세스 A (발신자)에서 데이터 생성
2️⃣ 운영체제(OS)가 데이터 전달 중개
3️⃣ 프로세스 B (수신자)에서 데이터 수신
이 과정에서 운영체제는 메모리를 보호하면서 데이터를 안전하게 교환하도록 IPC 기법을 제공한다.
💡 한 프로세스의 출력이 다른 프로세스의 입력으로 연결되는 방식
Process A (Writer) → Pipe → Process B (Reader)
📌 흐름
1️⃣ Process A가 Pipe를 생성
2️⃣ 데이터를 Pipe에 쓰기 (write)
3️⃣ Process B가 Pipe에서 데이터를 읽기 (read)
4️⃣ 데이터가 전달되면 Pipe는 자동 삭제됨
✅ 사용 예시
ls | grep txt ls(Process A)의 출력이 grep(Process B)의 입력으로 전달됨 💡 운영체제가 관리하는 메시지 큐를 사용하여 데이터를 주고받는 방식
Process A (Sender) → Message Queue → Process B (Receiver)
📌 흐름
1️⃣ Process A가 Message Queue를 생성
2️⃣ Process A가 큐에 메시지를 쓰기 (send message)
3️⃣ Process B가 메시지를 큐에서 읽기 (receive message)
4️⃣ 운영체제가 큐를 통해 메시지를 관리
✅ 사용 예시
💡 프로세스들이 같은 메모리 공간을 공유하여 데이터를 직접 주고받는 방식
Process A → Shared Memory → Process B
📌 흐름
1️⃣ Process A가 공유 메모리 공간을 생성
2️⃣ Process A가 데이터를 메모리에 저장
3️⃣ Process B가 같은 메모리를 읽어서 데이터 수신
4️⃣ 데이터가 유지되며 여러 프로세스가 접근 가능
✅ 사용 예시
⚠️ 주의할 점:
💡 네트워크를 통해 프로세스 간 데이터를 주고받는 방식
Client Process → Socket → Server Process
📌 흐름
1️⃣ 클라이언트 프로세스가 소켓을 생성하여 서버에 연결 요청
2️⃣ 서버 프로세스가 클라이언트의 요청을 수락
3️⃣ 클라이언트와 서버가 소켓을 통해 데이터 송수신
4️⃣ 연결이 끝나면 소켓을 닫음 (close)
✅ 사용 예시
운영체제(OS)와 프로세서(CPU)는 서로 협력하여 프로그램을 실행한다.
전체적인 동작 과정은 프로그램 실행 → 프로세스 생성 → CPU 스케줄링 → 명령어 처리 → 인터럽트 관리 순서로 진행된다.
1. 프로그램 실행 요청
2. 운영체제(OS)가 프로그램을 프로세스로 생성
3. 운영체제가 프로세스를 CPU 스케줄링 (Ready → Running)
4. CPU가 명령어를 가져와(페치) 실행
5. CPU가 메모리, 입출력(I/O) 요청을 수행
6. 프로세스가 종료되거나, 다른 프로세스로 교체(Context Switching)
7. 운영체제가 프로세스를 정리하고 자원을 반환
사용자: "크롬 브라우저 실행"
↓
운영체제: "chrome.exe 프로그램을 실행할 준비 완료!"
↓
프로그램을 프로세스로 변환
운영체제는 프로그램을 실행하기 위해 프로세스를 생성(Process Creation) 한다.
이 과정에서 운영체제는 다음과 같은 작업을 수행한다.
✅ 필요한 리소스 할당:
운영체제:
1. 프로세스를 생성하고 고유한 PID(Process ID) 부여
2. 프로그램 실행 코드를 메모리에 로드
3. 프로세스를 Ready 상태로 변경 (CPU 실행 대기)
📌 예제: 크롬 브라우저 실행
chrome.exe → Process A (PID: 1001) 생성
운영체제는 여러 개의 프로세스를 관리하며, CPU가 어떤 프로세스를 실행할지 결정한다.
이 과정에서 스케줄러(Scheduler) 가 작동한다.
✅ CPU 스케줄링 단계
1. Ready Queue 에 있는 프로세스 중 하나를 선택
2. CPU 할당 (Running 상태로 변경)
3. 일정 시간이 지나면 다른 프로세스로 교체 (Context Switching 발생)
운영체제:
1. 현재 실행 가능한 프로세스 목록 확인 (Ready Queue)
2. 스케줄링 알고리즘(FIFO, Round Robin 등)을 사용하여 실행할 프로세스 결정
3. 선택된 프로세스에 CPU 할당 (Ready → Running)
📌 예제: 크롬 브라우저가 실행되기 위한 CPU 스케줄링
[Ready Queue]
1. Chrome.exe (PID 1001)
2. VSCode.exe (PID 1002)
3. Spotify.exe (PID 1003)
운영체제:
→ Chrome.exe (PID 1001) 실행!
CPU는 실행 중인 프로세스의 명령어를 하나씩 가져와 실행(Fetch-Decode-Execute) 한다.
✅ CPU 명령어 실행 과정
1. Fetch (명령어 가져오기) → 명령어를 메모리에서 읽어옴
2. Decode (명령어 해석) → CPU가 명령어를 해석
3. Execute (명령어 실행) → 연산 수행, 결과 저장
4. Write-back (결과 저장) → 연산 결과를 레지스터 또는 메모리에 저장
1. CPU: "다음 명령어를 메모리에서 가져와!"
2. CPU: "명령어 해석 중..."
3. CPU: "명령어 실행 완료!"
4. CPU: "결과를 저장하고 다음 명령어를 실행!"
📌 예제: 크롬에서 웹 페이지 로드
1. CPU가 "페이지 로드" 명령어를 메모리에서 가져옴
2. CPU가 HTML 렌더링 명령어 실행
3. GPU에 렌더링 요청 전달
4. 결과를 화면에 표시
✅ 입출력 요청 흐름
프로세스: "파일 data.txt를 읽고 싶어!"
↓
운영체제: "디스크에서 data.txt 읽는 중... 기다려!"
↓
CPU는 다른 프로세스를 실행 (Context Switching)
↓
운영체제: "파일 로드 완료!"
↓
프로세스: "파일 데이터를 가져왔어!"
📌 예제: 크롬 브라우저에서 이미지 로드
1. 크롬: "이미지를 다운로드해!"
2. 운영체제: "네트워크 요청 처리 중..."
3. CPU는 다른 프로세스를 실행
4. 다운로드 완료 후 크롬이 다시 실행
✅ Context Switching 과정
1. 현재 실행 중인 프로세스의 상태 저장 (Register, Stack 등)
2. 새로운 프로세스의 상태 불러오기
3. CPU 제어권을 새로운 프로세스에게 넘김
📌 예제: 크롬이 이미지 로드를 기다리는 동안 VSCode 실행
1. 크롬이 네트워크 요청 중 (Waiting 상태)
2. CPU가 VSCode 실행 (Ready → Running)
3. 크롬의 네트워크 요청 완료되면 다시 실행
프로세스가 종료되면 운영체제는 사용했던 메모리, 파일 핸들, 네트워크 연결 등을 반환하여 다른 프로세스가 사용할 수 있도록 한다.
✅ 운영체제의 역할
1. 프로세스 상태를 "Terminated"로 변경
2. 사용하던 메모리 공간 해제
3. 파일 핸들 및 네트워크 연결 종료
4. 프로세스 ID(PID) 반환
📌 예제: 크롬 브라우저 종료
1. 사용자가 "Chrome 종료" 클릭
2. 운영체제: "프로세스 종료 중..."
3. 메모리 해제, 파일 닫기, 네트워크 연결 종료
4. 크롬 프로세스 완전히 종료됨
컨텍스트(Context)란?
컨텍스트는 프로세스가 실행되는 동안의 모든 정보를 의미하며, 일반적으로 다음과 같은 정보를 포함한다.
✅ 컨텍스트의 주요 구성 요소

📌 컨텍스트는 운영체제의 "프로세스 제어 블록(PCB, Process Control Block)"에 저장된다.
┌──────────────────────────────────────────────┐
│ 운영체제 (OS) │
│ ┌────────────────────────────────────────┐ │
│ │ 프로세스 테이블 │ │
│ │ ┌──────────────────────────────────┐ │ │
│ │ │ PCB (Process Control Block) │ │ │
│ │ │ ──────────────── │ │ │
│ │ │ 프로세스 ID (PID) │ │ │
│ │ │ 프로세스 상태 (Ready, Running) │ │ │
│ │ │ 프로그램 카운터 (PC) │ │ │
│ │ │ 레지스터 값 │ │ │
│ │ │ 메모리 정보 │ │ │
│ │ │ 스케줄링 정보 │ │ │
│ │ └──────────────────────────────────┘ │ │
│ │ ┌──────────────────────────────────┐ │ │
│ │ │ PCB (다른 프로세스) │ │ │
│ │ └──────────────────────────────────┘ │ │
│ └────────────────────────────────────────┘ │
└──────────────────────────────────────────────┘
✅ 즉, 현재 실행 중인 프로세스의 모든 상태 정보(컨텍스트)는 "PCB"에 저장된다!
💡 컨텍스트가 복원된다는 것은, 이전 프로세스가 중단된 시점부터 다시 실행된다는 의미이다.
✅ 컨텍스트 복원의 과정
1️⃣ 운영체제가 PCB에서 저장된 컨텍스트를 가져온다.
2️⃣ CPU 레지스터와 프로그램 카운터를 복원한다.
3️⃣ 이전 프로세스가 실행되던 시점부터 그대로 다시 실행된다.
┌─────────────────────────────────────┐
│ 기존 실행 중이던 프로세스 A │
│ - 프로그램 카운터: 0x0000234A │
│ - 레지스터 정보: rax=100, rbx=50 │
└─────────────────────────────────────┘
↓ 컨텍스트 저장 (PCB에 저장)
┌─────────────────────────────────────┐
│ 새로운 프로세스 B 실행 │
│ - 프로그램 카운터: 0x0000789B │
│ - 레지스터 정보: rax=20, rbx=30 │
└─────────────────────────────────────┘
↓ 프로세스 B 실행 종료, 다시 A 실행
┌─────────────────────────────────────┐
│ 프로세스 A의 컨텍스트 복원 │
│ - 프로그램 카운터: 0x0000234A │
│ - 레지스터 정보: rax=100, rbx=50 │
└─────────────────────────────────────┘
✅ 즉, 저장된 컨텍스트를 복원하면, 프로세스는 마치 멈춘 적이 없던 것처럼 다시 실행된다!