운영체제란?
운영체제가 하는 일의 종류
- 프로세스를 관리하기
- pc에 여러가지 프로그램을 한번에 켜 두면, 자연스럽게 지금 사용하지 않는 프로그램을 background에 둔다.
-
메모리 관리
- 하드웨어 관리
- 사용자가 하드웨어에 직접적으로 접근하는 것을 금지하고, 운영체제가 대신 관리해준다.
- 파일 시스템 관리
- 하드디스크에 많은 데이터를 효율적으로 저장하기 위함
운영체제의 구조
커널
- 운영체제의 핵심
- 프로세스, 메모리, 저장장치 관리
- 사용자는
인터페이스
를 통해 커널에 접근 가능. 인터페이스 = GUI, CLI- CLI: UNIX, LINUX가 기본적으로 제공하는 환경 (Command-Line Interace)
- 어플리케이션은
시스템콜
을 통해 커널에 접근 가능.- 시스템콜이 없이 어플리케이션에 직접 접근하면 중요한 데이터를 엎어씌워버릴 수도 있는데, 커널을 통해 write함수를 쓰면, 운영체제가 알아서 빈 메모리에 저장을 해줘서 안정성이 있다.
- 하드웨어 <-> 커널 인터페이스 : 드라이버
하드웨어의 구조
폰 노이만 구조
폰 노이만은 하드웨어 중심의 프로그램을 개선하기 위해, CPU와 메모리RAM
을 잇는 Bus(데이터를 전달하는 통로)를 만든다.
프로그램은 메모리에 올려 실행하는데, 이를 프로그램 내장방식이라 한다.
메모리에 올라간 프로그램은 배선을 바꾸는 대신, 소프트웨어만 바꿔주면 되도록 개선되었다.
메인보드
- 다른 하드웨어를 연결하는 장치
- 장치간에 데이터를 전달하는 것은 Bus가 담당
CPU Central Processing Unit
중앙처리장치
- 산술논리 연산장치
Arithmetic and Logic Unit
: CPU에서 실제로 데이터 연산을 담당함 - 제어장치
Control Unit
: 모든 장치들의 동작을 지시 - 레지스터: CPU내에서 계산을 위해 임시로 보관하는 장치
메모리의 종류
RAM Random Access Memory
- 랜덤으로 데이터를 읽어도 저장된 위치와 상관없이 읽는 속도가 같다.
- 전력이 끊기면 메모리를 잃기 때문에 메인메모리로 사용됨
ROM Read Only Memory
- 전력이 끊겨도 메모리를 갖고 있지만, 한번 쓰면 수정할 수 없음
- 부팅과 관련된 바이오스를 저장하는데 주로 쓰인다.
컴퓨터를 켜면 일어나는 일
- BIOS가 하드웨어가 괜찮은지 확인한다.
- 하드웨어에 이상이 없다면, 하드디스크에 있는 마스터 부트 레코드에 저장된 부트로더를 메모리로 가져와서 실행시키낟.
- 운영체제가 여러개 설치 되어 있는 경우, 운영체제를 선택하라는 화면이 나옴
- 운영체제가 실행되면, 이제부터 실행되는 모든 프로그램은 메모리에 올라와서 운영체제가 관리한다.
프로그램과 프로세스
프로그램이란?
프로그램이란 하드디스크 등과 같은 저장장치에 저장된 명령문의 집합체를 말한다.
프로그램은 저장장치만 사용하는 수동적인 작업이다.
프로세스란?
프로세스란 실행중인 프로그램이다. 하드디스크에 올라간 프로그램이 메모리에 올라갔을 때, 실행중이라고 한다.
프로세스는 CPU도 사용하고, 입출력 작업도 하기 때문에 능동적인 작업이다.
Code 영역
프로세스를 실행하는 코드를 저장함
Data 영역
전역변수와 Static 변수를 저장
Heap 영역
프로그래머가 런타임시 할당할 수 있는 메모리 공간
- C언어
- malloc() : 힙영역에 메모리 공간 할당
- free() : 할당된 메모리 공간 해제
Stack 영역
지역변수와 함수 호출을 했을 때 필요한 정보 저장
컴파일 과정
- 전처리기
- 파일의 확장자가 i가 됨
- 컴파일러가 컴파일 수행
- 고수준인 c언어를 저수준인 어셈플리 언어로 바꿔줜다.
- 컴파일러 확장자가 s가 됨
유니 프로그래밍과 멀티 프로그래밍
유니프로그래밍
- 메모리에 프로세스 1개
- 하나의 프로세스를 끝내야 다른 프로세스를 시작할 수 있다.
멀티 프로그래밍
- 메모리에 프로세스 n개
- CPU가 쉬는 시간이 줄어들어 효율성이 높아진다
- 멀티 태스킹: 한 프로세스를 짧게 실행하고, 다른 모든 프로세스도 짧게 실행하면서, 모든 프로세스를 동시에 실행시키는 것처럼 느껴지게 하는 기술
- 멀티 프로세서: CPU가 여러개 있는 것
- 멀티 프로그래밍: 멀티 프로세서로 실행하는 것
PCB Process Control Block
PCB란, 프로세스가 만들어지면 해당 프로세스의 정보를 가지고 있는 PCB를 저장한다. 여러개의 PCB는 연결리스트로 구성되어 있다.
프로세스가 종료되면, 해당 프로세스의 PCB를 제거하고, 연결리스트는 유지한다.
PCB의 구성
프로세스 상태
시분할을 사용하는 운영체제는 여러개의 프로세스를 돌아가면서 실행한다. 한 순간에 하나의 프로세스만 실행하지만, 속도가 빨라서 여러 개를 동시에 실행하는 것 처럼 보임
- 생성
New
: PCB를 생성하고 메모리에 프로그램 적재를 요청한 상태 - 준비
Ready
: 메모리에 프로그램 적재를 승인 받으면 준비 상태로 넘어간다. CPU를 사용하기 위해 기다리는 상태. CPU 스케줄러에 의해 CPU가 할당됨. 대부분의 프로세는 준비상태이다. - 실행
Running
: 준비상태에 있는 프로세스가 CPU 스케줄러에 의해 CPU를 할당받아 실행되는 상태. CPU가 n개라면, 실행상태에 있을 수 있는 프로세스의 수는 n개. 실행상태에 있는 프로세스도 부여된 시간만큼만 실행 가능. 시간이 끝나면 다시 준비상태로 들어간다. - 대기
Waiting
: 프로세스가 입출력 요청을 하면 입출력이 완료될 때까지 대기상태로 빠진다. 입출력 작업이 끝나고 다시 준비 상태로 들어간다. - 완료
Terminated
: 프로세스가 사용했던 데이터를 메모리에서 제거, 생성된 PCB도 제거
컨텍스트 스위칭
- 프로세스를 실행하는 중에 다른 프로세스를 실행하기 위해, 실행중인 프로세스의 상태를 저장하고, 다른 프로세스의 상태값으로 교체하는 작업
- 컨텍스트 스위칭이 일어날 대, PCB의 아래 내용이 바뀜
- 프로세스 상태
- 프로그램 카운터: 다음 실행할 명령어의 주소
- 레지스터 정보
- 메모리 관련 정보
쓰레드
- 운영체제가 작업을 처리하는 단위
- 쓰레드는 프로세스 내에 존재한다. 1개의 프로세스 내에 n개의 쓰레드가 있을 수 있다.
- code, data, heap 영역은 쓰레드가 공유하고, stack은 각각 생성한다.
- Thread 별로 id가 있고, Thread Control Block이 관리한다.
- 쓰레드를 사용하면 데이터 공유시 오버헤드가 적다. 그치만 데이터를 공유하기 때문에 문제가 생길 수도 있다.
CPU 스케줄링
준비중인 프로세스들은 CPU를 할당받아 실행되는데, 이것을 CPU 스케줄링이라고 한다.
CPU스케줄러는 아래 내용을 고려해서 스케줄링을 한다.
- 어떤 프로세스에게 CPU를 할당할 것인가?
- 프로세스는 얼마나 오래 CPU를 사용해도 되는가?
다중 큐
프로세스가 대기하고 있는 준비상태, 대기상태는 큐로 관리된다. Queue는 FIFO 구조이다.
프로세스가 실행상태에서 준비상태로 돌아갈 때, 운영체제는 우선순위를 보고, PCB를 준비 큐에 넣는다.
CPU 스케줄러는 준비 큐에 있는 PCB 중에 적당한 PCB를 실행상태로 보낸다.
스케줄링 목표
-
리소스 사용률: CPU의 사용률, I/O 디바이스의 사용률
-
오버헤드 최소화: 컨텍스트 스위칭을 너무 자주하면, 오버헤드가 발생
-
공평성: 모든 CPU에게 공평하게 할당되어야 한다. (공평함의 의미는 무조건 n분의 1은 아니다)
-
처리량: 같은 시간동안 내에 더 많은 것을 처리할 수 있어야 한다.
-
대기시간: 작업 요청 후 실제 실행 시간까지 대기시간이 짧아야 한다.
-
응답시간: 응답시간이 짧아야 한다.
스케줄링 알고리즘
스케줄링의 성능은 평균 대기시간으로 평가된다. 프로세스들이 모두 실행되기까지의 평균 대기시간이다.
FIFO
먼저 스케줄링 큐에 들어온 프로세스가 먼저 스케줄을 할당받는다.
ex) 마트 계산대
- 장점: 단순하고 직관적인다
- 단점
- 한 프로세스가 끝나야 다음 프로세스가 실행되기 때문에, 실행시간이 짧은 프로세스도 앞 프로세스가 끝날 때까지 기다려야 한다.
- 앞의 프로세스에 I/O 작업이 있을 경우 처리량이 떨어진다.
- 프로세스의 Burst Time에 따라 성능 차이가 심하게 나서 실제로는 잘 쓰이지 않는다.
SJF Shortest Job First
Burst Time이 짧은 프로세스 먼저 실행한다.
- FIFO의 단점을 극복하기 위해 등장했다.
- 단점
- 어떤 프로세스가 먼저 실행될지 예측하기 힘들다.
- Burst time이 긴 프로세스는 아주 오래 기다릴 수도 있다. 중간에 Burst time이 짧은 프로세스가 들어오면 계속 대기시간이 늘어지기 때문이다.
- 실제로는 잘 쓰이지 않는다.
RR Round Robin
한 프로세스에서 일정시간동안 CPU를 할당하고, 할당량이 지나면 강제로 다른 프로세스에게 일정시간만큼 CPU를 할당한다. 할당 받은 시간이 끝난 프로세스는 다시 맨 마지막 순서로 들어간다.
- 타임 슬라이스: 프로세스가 할당하는 시간
- RR은 컨텍스트 스위칭 시간이 포함된다. 타임슬라이스 값에 따라 대기시간이 달라진다.
- 같은 시간이 걸린다면 FIFO보다 RR이 비효율적이다.
MLFQ Multi Level Feedback Queue
RR의 업그레이드된 버전
- CPU Bound Process에 큰 크기의 타임슬라이스 적용
- I/O Bound Process에 작은 크기의 타임슬라이스 적용
우선순위를 가진 큐를 여러개 준비해두고, 우선순위가 낮을수록 타임슬라이스가 커지고, 우선순위가 높을수록 타임슬라이스가 짧다.
프로세스간 동기화
프로세스간 통신의 종류
- 한 컴퓨터 내에서 file과 pipe를 이용해서 통신하기
- 한 프로세스 내에서 쓰레드간 통신하기
- 다른 컴퓨터와 socket 통신, RPC(원격통신호출)
공유자원과 임계구역
- 임계구역
Critical Section
: 여러 프로세스가 동시에 사용하면 안되는 영역 - 상호배제
Mutual Exclusion
의 요구사항- 임계영역엔 동시에 하나의 프로세스만 접근한다.
- 여러 요청에도 하나의 프로세스의 접근만 허용한다.
- 임계구역에 들어간 프로세스는 빠르게 나와야 한다.
세마포어 Semaphore
임계구역에 진입하는 것을 lock을 통해 제어함
모니터
프로그래밍 언어 차원에서 지원
- 자바에서는 synchronized를 사용하면 모니터링 된다.
- 하나의 변수에 synchronnized가 붙은 여러 함수(ex, increase, decrease)가 있다면, increase를 사용하는 중이라면 다른 프로세스에서 decrease도 접근 못하게 막는다.
교착상태
교착상태가 발생하는 이유는 공유자원 때문이다.
식사하는 철학자
원탁에 3명의 철학자가 앉아서 식사를 하는데, 포크가 각각 2개 필요하지만 포크가 3개만 있을 때.
한 명이 2 포크를 들고 식사를 하면 나머지 2명의 철학자는 사유를 하면서 대기를 한다.
각자 1개의 포크를 들고 식사를 하려고 하면, 아무도 식사를 못하고 다른 사람이 먼저 먹고 포크를 반환하기를 기다린다.
교착상태의 필요조건
- 상호배제
- 비선점
- 점유와 대기
- 원형 대기
교착 상태의 해결 방법: 교착상태 회피 Deadlock avoidance
- 프로세스들에게 자원을 할당할 때, 어느 정도이면 교착상태가 생기는지 파악해서 그것을 회피할 수 있을 정도로만 할당함
- 은행원 알고리즘
가벼운 교착상태 검출
타이머를 이용하여 프로세스가 일정 시간동안 작업을 진행하지 않는다면, 교착상태가 발생했다고 간주하고 교착상태를 해결한다.
일정시점마다 체크포인트를 만들어 저장하고, 타임아웃으로 교착상태가 발생했다면 마지막 저장한 체크포인트로 돌아간다.
무거운 교착상태 검출
자원할당 그래프를 사용하여 검출하는 방식
현재 운영체제에서 프로세스가 어떤 자원을 사용하는지 지켜보고, 교착상태를 검출해낸다.
교착상태 검출시 교착상태를 일으킨 프로세스를 강제 종료하고, 다시 실행시킬 때 체크포인트로 돌아간다.
컴파일
- 컴파일언어: 개발자가 코드를 작성하고 컴파일을 거쳐서 0과 1로 된 실행파일을 만든다. 컴파일 과정에서 개발자가 만든 문법 오류를 찾고, 기계어로 만든다.
- 인터프리터언어: 미리 검사하지 안혹, 실행시 코드를 한 줄씩 검사하며 실행한다. 속도가 컴파일 언어와 비교해 느리다. JS, Python이 이에 해당한다.
컴파일 과정
test.c 파일 -> 전처리기 -> test.i가 됨 -> 컴파일러 -> test.s가 됨 -> 어셈블러 -> test.o가 됨 -> 링커 -> test.exe
운영체제는 exe파일에 있는 코드영역과 데이터 영역을 가져와서 데이터 영역에 할당하고 빈 상태의 heap과 stack을 할당한다.
PCB를만들어 관리되도록 하고, 프로그램 카운터를 생성한 프로세스의 코드영역 첫번째 주소를 할당한다.
Reference
그림으로 배우는 운영체제