운영체제란?
운영체제의 역할
- 프로세스 관리
- 저장장치 관리
- 네트워킹
- 사용자 관리
- 디바이스 드라이버
1. 프로세스 관리
운영체제는 컴퓨터 시스템에서 실행되는 모든 프로세스를 관리합니다. 프로세스는 컴퓨터에서 실행되는 프로그램의 인스턴스를 나타내며, 각 프로세스는 운영체제로부터 시스템 자원을 할당받습니다. 운영체제는 프로세스 스케쥴링, 프로세스 생성 및 종료, 프로세스 동기화, 프로세스 간 통신 등의 기능을 제공합니다.
2. 저장장치 관리
운영체제는 컴퓨터의 주 기억장치와 보조 기억장치를 관리합니다. 이는 파일 시스템을 포함한 저장 공간의 할당, 효율적인 저장 공간의 사용, 데이터의 읽기 및 쓰기, 보조 저장장치와의 통신 등을 포함합니다.
3. 네트워킹
운영체제는 컴퓨터와 네트워크 간의 통신을 관리합니다. 이는 데이터의 전송과 수신, 네트워크 장치 관리, 네트워크 프로토콜 지원 등을 포함합니다. 운영체제는 컴퓨터가 네트워크에 안전하게 접속하고 효율적으로 통신할 수 있도록 돕습니다.
4. 사용자 관리
운영체제는 사용자 계정을 관리하고, 사용자의 권한을 제어하며, 사용자 간의 자원 공유를 관리합니다. 이를 통해, 특정 사용자가 시스템의 특정 부분에 접근하거나 특정 작업을 수행하는 것을 허용하거나 제한할 수 있습니다.
5. 디바이스 드라이버
운영체제는 컴퓨터 하드웨어를 제어하는 소프트웨어인 디바이스 드라이버를 관리합니다. 디바이스 드라이버는 하드웨어와 운영체제 사이에서 인터페이스 역할을 하여, 운영체제가 하드웨어를 제어하고 하드웨어에서 정보를 가져올 수 있도록 돕습니다. 디바이스 드라이버는 프린터, 디스플레이, 키보드 등 다양한 하드웨어 장치를 지원합니다.
프로세스와 스레드
프로세스 : 프로그램을 메모리 상에서 실행중인 작업
스레드 : 프로세스 안에서 실행되는 여러 흐름 단위
프로세스는 자신만의 고유 공간과 자원을 할당받아 사용하는데 반해, 스레드는 다른 스레드와 공간, 자원을 공유하면서 사용하는 차이가 존재함

프로세스는 각각 별도의 주소공간 할당 (독립적)
- Code : 코드 자체를 구성하는 메모리 영역(프로그램 명령)
- Data : 전역변수, 정적변수, 배열 등
- 초기화 된 데이터는 data 영역에 저장
- 초기화 되지 않은 데이터는 bss 영역에 저장
- Heap : 동적 할당 시 사용 (new(), malloc() 등)
- Stack : 지역변수, 매개변수, 리턴 값 (임시 메모리 영역)
멀티프로세스
하나의 프로그램을 여러개의 프로세스로 구성하여 각 프로세스가 병렬적으로 작업을 수행하는 것
- 장점 : 안전성 (메모리 침범 문제를 OS 차원에서 해결)
- 단점 : 각각 독립된 메모리 영역을 갖고 있어, 작업량 많을 수록 오버헤드 발생. Context Switching으로 인한 성능 저하
멀티스레드
하나의 응용 프로그램에서 여러 스레드를 구성해 각 스레드가 하나의 작업을 처리하는 것
스레드들이 공유 메모리를 통해 다수의 작업을 동시에 처리하도록 해줌
- 장점 : 독립적인 프로세스에 비해 공유 메모리만큼의 시간, 자원 손실이 감소 전역 변수와 정적 변수에 대한 자료 공유 가능
- 단점 : 안전성 문제. 하나의 스레드가 데이터 공간 망가뜨리면, 모든 스레드가 작동 불능 상태 (공유 메모리를 갖기 때문)
- 멀티스레드의 안전성에 대한 단점은 Critical Section 기법을 통해 대비함
- 하나의 스레드가 공유 데이터 값을 변경하는 시점에 다른 스레드가 그 값을 읽으려할 때 발생하는 문제를 해결하기 위한 동기화 과정
- 상호 배제, 진행, 한정된 대기를 충족해야함
프로세스 주소 공간
프로그램이 CPU에 의해 실행됨 → 프로세스가 생성되고 메모리에 프로세스 주소 공간이 할당됨
프로세스 주소 공간에는 코드, 데이터, 스택으로 이루어져 있다.
- 코드 Segment : 프로그램 소스 코드 저장
- 데이터 Segment : 전역 변수 저장
- 스택 Segment : 함수, 지역 변수 저장
인터럽트 (Interrupt)
프로그램을 실행하는 도중에 예기치 않은 상황이 발생할 경우 현재 실행 중인 작업을 즉시 중단하고, 발생된 상황에 대한 우선 처리가 필요함을 CPU에게 알리는 것
외부 인터럽트
- CPU의 하드웨어 신호에 의해 발생
- 입출력 장치, 타이밍 장치, 전원 등 외부적인 요인으로 발생
- 전원 이상, 기계 착오, 외부 신호, 입출력
내부 인터럽트
- CPU의 하드웨어 신호에 의해 발생
- Trap이라고 부르며, 잘못된 명령이나 데이터를 사용할 때 발생
- 0으로 나누기가 발생, 오버플로우, 명령어를 잘못 사용한 경우 (Exception)
소프트웨어 인터럽트
- 명령어의 수행에 의해 발생
- 프로그램 처리 중 명령의 요청에 의해 발생한 것 (SVC 인터럽트)
- 사용자가 프로그램을 실행시킬 때 발생
- 소프트웨어 이용 중에 다른 프로세스를 실행시키면 시분할 처리를 위해 자원 할당 동작이 수행된다.
인터럽트 처리 과정

- 주 프로그램이 실행되다가 인터럽트가 발생했다.
- 현재 수행 중인 프로그램을 멈추고, 상태 레지스터와 PC 등을 스택에 잠시 저장한 뒤에 인터럽트 서비스 루틴으로 간다.
(잠시 저장하는 이유는, 인터럽트 서비스 루틴이 끝난 뒤 다시 원래 작업으로 돌아와야 하기 때문)
- 만약 인터럽트 기능이 없었다면, 컨트롤러는 특정한 어떤 일을 할 시기를 알기 위해 계속 체크를 해야 한다. (이를 폴링(Polling)이라고 한다)
- 폴링을 하는 시간에는 원래 하던 일에 집중할 수가 없게 되어 많은 기능을 제대로 수행하지 못하는 단점이 있었다.
시스템 콜 (System Call)
프로세스 생성과 제어를 담당하는 명령어
fork()
새로운 프로세스를 생성할 때 사용
fork()가 실행되면?
- 프로세스가 하나 더 생김
- 이 때 생긴 프로세스(Child)는 fork를 만든 프로세스(Parent)와 (almost) 동일한 복사본을 갖게 됨
- parent의 fork() 값은 child의 PID를 리턴
- child의 fork() 값은 0을 리턴
exec()
child 프로세스가 종료될 때까지 기다림
- wait를 통해서, child의 실행이 끝날 때까지 기다려줌
- parent가 먼저 실행되더라도, wait ()는 child가 끝나기 전에는 return하지 않으므로, 반드시 child가 먼저 실행됨.
wait()
child에서는 parent와 다른 동작을 하고 싶을 때
- code segment 영역에 실행 파일의 코드를 읽어와서 덮어 씌운다
- 씌운 이후에는, heap, stack, 다른 메모리 영역이 초기화되고, OS는 그냥 실행한다.
- 즉, 새로운 Process를 생성하지 않고, 현재 프로그램에 wc라는 파일을 실행한다.
PCB와 Context Switching
Process Management
CPU가 프로세스가 여러개일 때, CPU 스케줄링을 통해 관리하는 것
프로세스에 대한 데이터는 metadata이고, 이를 PCB(Process Control Block)에 저장해 CPU가 프로세스를 관리
- Process Metadata
- Process ID
- Process State
- Process Priority
- CPU Registers
- Owner
- CPU Usage
- Memeory Usage
PCB(Process Control Block)
프로세스 메타데이터들을 저장해 놓는 곳, 한 PCB 안에는 한 프로세스의 정보가 담김

- Context Switching을 위해, 앞으로 다시 수행할 대기 중인 프로세스에 관한 저장 값을 PCB에 저장해두는 것
- Linked List 방식으로 관리
Context Switching
CPU가 이전의 프로세스 상태를 PCB에 보관하고, 또 다른 프로세스의 정보를 PCB에 읽어 레지스터에 적재하는 과정
- 보통 인터럽트가 발생하거나, 실행 중인 CPU 사용 허가시간을 모두 소모하거나, 입출력을 위해 대기해야 하는 경우에 Context Switching이 발생한다.
- 즉, 프로세스가 Ready → Running, Running → Ready, Running → Waiting처럼 상태 변경 시 발생!
IPC (Inter Process Communication)
독립적으로 실행되는 프로세스 간 통신을 가능케 하는 기술
IPC 종류
익명 PIPE
- 파이프는 두 개의 프로세스를 연결
- 하나의 프로세스는 데이터를 쓰기만 하고, 다른 하나는 데이터를 읽기만 할 수 있음
- 한쪽 방향으로만 통신이 가능한 반이중 통신이라고도 부른다.
- 따라서 양쪽으로 모두 송/수신을 하고 싶으면 2개의 파이프를 만들어야 한다.
- 매우 간단하게 사용할 수 있는 장점이 있고, 단순한 데이터 흐름을 가질 땐 파이프를 사용하는 것이 효율적이다.
- 단점으로는 전이중 통신을 위해 2개를 만들어야 할 때는 구현이 복잡해지게 된다.
- 통신할 프로세스를 명확히 알 수 있는 경우에 사용
(부모-자식 프로세스 간 통신처럼)
Named PIPE(FIFO)
- 전혀 모르는 상태의 프로세스들 사이 통신에 사용
- 즉, 익명 파이프의 확장된 상태로 부모 프로세스와 무관한 다른 프로세스도 통신이 가능한 것 (통신을 위해 이름있는 파일을 사용)
- 하지만, Named 파이프 역시 읽기/쓰기 동시에 불가능함.
- 따라서 전이중 통신을 위해서는 익명 파이프처럼 2개를 만들어야 가능
Message Queue
- 입출력 방식은 Named 파이프와 동일함
- 다른점은 메시지 큐는 파이프처럼 데이터의 흐름이 아니라 메모리 공간이다.
- 사용할 데이터에 번호를 붙이면서 여러 프로세스가 동시에 데이터를 쉽게 다룰 수 있다.
공유 메모리
-
파이프, 메시지 큐가 통신을 이용한 설비라면, 공유 메모리는 데이터 자체를 공유하도록 지원하는 설비다.
-
프로세스의 메모리 영역은 독립적으로 가지며 다른 프로세스가 접근하지 못하도록 반드시 보호되야한다. 하지만 다른 프로세스가 데이터를 사용하도록 해야하는 상황도 필요할 것이다. 파이프를 이용해 통신을 통해 데이터 전달도 가능하지만, 스레드처럼 메모리를 공유하도록 해준다면 더욱 편할 것이다.
-
공유 메모리는 프로세스간 메모리 영역을 공유해서 사용할 수 있도록 허용해준다.
-
프로세스가 공유 메모리 할당을 커널에 요청하면, 커널은 해당 프로세스에 메모리 공간을 할당해주고 이후 모든 프로세스는 해당 메모리 영역에 접근할 수 있게 된다.
-
중개자 없이 곧바로 메모리에 접근할 수 있어서 IPC 중에 가장 빠르게 작동함
메모리 맵
- 공유 메모리처럼 메모리를 공유해준다.
- 메모리 맵은 열린 파일을 메모리에 맵핑시켜서 공유하는 방식이다.
(즉 공유 매개체가 파일+메모리)
- 주로 파일로 대용량 데이터를 공유해야 할 때 사용한다.
소켓
- 네트워크 소켓 통신을 통해 데이터를 공유한다.
- 클라이언트와 서버가 소켓을 통해서 통신하는 구조로, 원격에서 프로세스 간 데이터를 공유할 때 사용한다.
- 서버(bind, listen, accept), 클라이언트(connect)
CPU 스케줄링
초기 스케줄링
조건 : 오버헤드↓, 사용률↑, 기아 현상↓
Batch System
- 가능하면 많은 일을 수행. 시간(time) 보단 처리량(throughout)이 중요
Interactive System
Real-time System
선점 / 비선점 스케줄링
선점 (preemptive)
- OS가 CPU의 사용권을 선점할 수 있는 경우, 강제 회수하는 경우 (처리시간 예측 어려움)
비선점 (nonpreemptive)
- 프로세스 종료 or I/O 등의 이벤트가 있을 때까지 실행 보장 (처리시간 예측 용이함)
스케줄링 알고리즘 종류
비선점 스케줄링
- FCFS (First Come First Served)
- 큐에 도착한 순서대로 CPU 할당
- 실행 시간이 짧은 게 뒤로 가면 평균 대기 시간이 길어짐
- SJF (Shortest Job First)
- 수행시간이 가장 짧다고 판단되는 작업을 먼저 수행
- FCFS 보다 평균 대기 시간 감소, 짧은 작업에 유리
- HRN (Hightest Response-ratio Next)
- 우선순위를 계산하여 점유 불평등을 보완한 방법(SJF의 단점 보완)
- 우선순위 = (대기시간 + 실행시간) / (실행시간)
선점 스케줄링
- Priority Scheduling
- 정적/동적으로 우선순위를 부여하여 우선순위가 높은 순서대로 처리
- 우선 순위가 낮은 프로세스가 무한정 기다리는 Starvation 이 생길 수 있음
- Aging 방법으로 Starvation 문제 해결 가능
- Round Robin
- FCFS에 의해 프로세스들이 보내지면 각 프로세스는 동일한 시간의 Time Quantum 만큼 CPU를 할달 받음
- Time Quantum or Time Slice : 실행의 최소 단위 시간
- 할당 시간(Time Quantum)이 크면 FCFS와 같게 되고, 작으면 문맥 교환 (Context Switching) 잦아져서 오버헤드 증가
- Multilevel-Queue
- 작업들을 여러 종류의 그룹으로 나누어 여러 개의 큐를 이용하는 기법
- 우선순위가 낮은 큐들이 실행 못하는 걸 방지하고자 각 큐마다 다른 Time Quantum을 설정 해주는 방식 사용
- 우선순위가 높은 큐는 작은 Time Quantum 할당. 우선순위가 낮은 큐는 큰 Time Quantum 할당.
- Multileve-feedback-queue
- 다단계 큐에서 자신의 Time Quantum을 다 채운 프로세스는 밑으로 내려가고 자신의 Time Quantum을 다 채우지 못한 프로세스는 원래 큐 그대로
- Time Quantum을 다 채운 프로세스는 CPU burst 프로세스로 판단하기 때문
- 짧은 작업에 유리, 입출력 위주(Interrupt가 잦은) 작업에 우선권을 줌
- 처리 시간이 짧은 프로세스를 먼저 처리하기 때문에 Turnaround 평균 시간을 줄옂줌