Skip to content

Latest commit

 

History

History

OS

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

OS


운영체제 정의
  • 하드웨어(CPU, 메모리, 디스크 등)를 관리
  • 응용 프로그램과 하드웨어 사이에서 인터페이스 역할을 하는 시스템 소프트웨어
  • 시스템의 자원과 동작을 관리하는 소프트웨어
  • 프로세스, 저장장치, 네트워킹, 사용자, 하드웨어 관리
프로세스와 스레드의 차이
  • 프로세스는 실행중인 프로그램으로 OS로부터 자원을 할당받아 실행, 코드/데이터/스택/힙 메모리 영역을 가짐
  • 프로세스의 독립적인 실행 단위로 프로세스로부터 자원을 할당받아 실행, 프로세스의 코드/데이터/힙 메모리 영역을 공유하고 개별적인 스택을 가짐
스레드가 개별적인 스택을 가지는 이유
  • 스택에는 함수 호출 시의 전달인자, 지역 변수, 되돌아갈 주소 등을 저장
  • 독립적인 스택을 갖는 것은 독립적인 함수 호출이 가능하고 독립적인 실행 흐름을 추가할 수 있다는 것을 의미
스레드가 PC 레지스터를 가지는 이유
  • 스레드는 CPU를 할당/반납하고를 반복
  • 이전까지의 수행 내역을 기억하기 위해 독립적인 PC 사용
프로세스 메모리 구성
  • 코드: 프로그램의 코드 저장
  • 데이터: 전역 변수, 정적 변수 저장
  • 스택: 지역 변수, 매개 변수, 함수의 호출과 할당, 컴파일에 크기 결정
  • 힙: 동적으로 할당 및 해제, 런 타임에 크기 결정
힙과 스택의 차이
  • 힙: 프로그램 코드에서 동적으로 할당하여 사용되는 메모리 영역
  • 스택: 함수를 호출할 때나 지역변수를 지정할 때 자동으로 할당되는 메모리 영역
스택의 장점과 단점
  • 장점: 자동으로 처리되기 때문에 낭비되는 공간이 없고 사용하기가 편리
  • 단점: 한계가 있어 한계를 초과하도록 삽입할 수 없고 유연성이 부족
힙의 장점과 단점
  • 장점: 프로그램에 필요한 개체의 개수나 크기를 미리 알 수 없는 경우 사용하고 개체가 너무 커서 스택 할당자에 맞지 않는 경우 사용 가능
  • 단점: 할당/해제 작업으로 인한 속도 저하
프로세스 생성과정
  • 프로세스 관리 정보를 갖는 Process Control Block를 생성하고 프로그램의 코드를 읽어 들여 코드 영역을 메모리에 할당
  • 초기화된 전역 변수 및 static 변수인 데이터 영역을 메모리에 할당
  • 힙과 스택의 초기 메모리 주소를 초기화
  • Queue에서 프로세스가 등록되고 운영체제가 CPU를 할당하기를 대기
PCB (Process Control Block)
  • 프로세스 관리 정보를 저장하는 커널의 자료구조 (Data 영역에 존재)
  • Process 상태, PC(다음에 수행할 명령어의 주소), CPU 레지스터, CPU 스케줄링 정보, 메모리 관리 정보 등을 저장
  • 문맥 교환 시에 진행 사항을 PCB에 저장하고 CPU 반환 -> CPU를 할당받으면 PCB에 저장되어 있는 내용을 불러와 이전에 종료되었던 시점부터 다시 수행
문맥 교환 (Context Switching)

image

  • 실행 중이던 프로세스를 중단하고 다른 프로세스를 실행할 때 발생
  • 프로세스 사이에서 CPU 제어권이 이동되는 것
  • 문맥: CPU에서 프로세스를 실행하는데 필요한 프로세스의 정보, 각 프로세스의 PCB에 저장
  • 멀티 스레드에서는 문맥 교환 시 스택 영역을 제외한 모든 영역을 공유하기 때문에 문맥 교환 비용이 훨씬 적음
  • 과정
    1. 실행 중이던 프로세스의상태(문맥)를 PCB에 보관
    2. 새로운 프로세스의 PCB에서 문맥(Context)을 복원해 레지스터에 적재
    3. 새로운 프로세스 실행
인터럽트
  • 프로그램을 실행하는 도중에 예기치 않은 상황이 발생할 경우 현재 실행 중인 작업을 즉시 중단하고, 발생된 상황을 우선 처리한 후 실행 중이던 작업으로 복귀하여 계속 처리하는 것
  • 문맥 교환을 구현할 때 Timer Interrupt를 통해서 제어권을 커널이 가져올 수 있도록 활용
멀티 프로세스
  • 여러 프로세서(CPU)가 여러 작업(Task)을 동시에 처리하는 것 (병렬 처리)
  • 안전성: 하나의 프로세스가 죽더라도 다른 프로세스에는 영향을 끼치지 않고 정상적으로 수행
  • 통신 비용/문맥 교환 비용이 큼
    • CPU는 한 번에 하나의 프로세스만 실행 가능 -> 여러 프로세스를 돌아가면서 실행
      • IPC (Inter Process Communication): 프로세스 간의 통신을 하는 것
        • 파일 공유, 커널 영역 이용(메시지 큐, 공유 메모리, 소켓 등)
  • 많은 메모리 공간을 차지
멀티 스레드
  • 하나의 프로세스에 여러 스레드가 자원을 공유하며 작업을 나누어 하는 것
  • 안전성 낮음: 하나의 스레드의 비정상적인 활동은 전체 스레드에 영향을 끼칠 수 있음
  • 통신 비용 적음
    • 코드/데이터/힙 영역을 공유메모리를 적게 차지하고 공유 메모리가 없어도 통신 가능
  • 문맥 교환 비용 적음
  • 프로세스를 생성하여 자원을 할당하는 시스템 콜이 감소함으로서 자원을 효율적으로 관리
Thread Safe
  • 멀티 스레딩에서 하나의 자원에 여러 스레드가 동시에 접근해도 프로그램 실행의 문제가 없는 상태
  • Thread Safe한 코드: Critical Section을 통해 스레드 내부에서 처리되는 연산들을 직렬화(Serialize) 하여 한 번에 한 스레드에서 연산이 수행
병렬성과 동시성의 차이
  • 병렬성: 멀티 코어에서의 멀티 스레드, 각 코어들의 스레드가 동시에 실행
  • 동시성: 싱글 코어에서의 멀티 스레드, 여러 개의 스레드가 번갈아가며 실행
Critical Section(공유 자원, 임계 영역)
  • 동일한 자원에 동시에 접근하는 경우가 발생하는 코드 영역
  • 접근 순서에 따라 실행 결과가 달라지는 구역
Race Condition
  • 공유 자원에 여러 프로세스/스레드가 접근할 경우 접근 순서에 따라 결과가 달라지는 현상
뮤텍스와 세마포어
  • 상호 배제를 달성하는 기법
    • 상호 배제: 둘 이상의 프로세스/스레드가 동시에 임계 영역에 진입하는 것을 방지하기 위해 사용하는 알고리즘
  • 상호 배제만 필요하면 뮤텍스, 실행 순서 동기화 또는 두개 이상의 프로세스/스레드가 접근해야 되면 세마포어를 사용

뮤텍스 (Mutual Exclusion)

  • 동기화 대상이 1개일 때 사용 -> 1개 프로세스/스레드만 접근 가능
    • 바이너리 세마포어와 비슷함
  • 자원 소유 가능: 을 소유한 스레드만이 락을 반환할 수 있음
  • Deadlock이 발생할 수 있음

세마포어 (Semaphore)

  • 동기화 대상이 여러 개일 때 사용 -> 세마포어 변수(Counter)만큼의 프로세스/스레드 접근 가능
    • 1: 바이너리 세마포어
    • 2 이상: 카운팅 세마포어
  • Signaling mechanism
    • wait(): 세마포어 변수 1감소 -> Critical Section -> signal(): 세마포어 변수 1증가
  • 자원 소유 불가: wait()와 signal()을 호출하는 존재가 다를 수 있음
  • Deadlock이 발생할 수 있음
뮤텍스와 모니터

뮤텍스

  • 다른 프로세스간 동기화에 사용 가능

모니터

  • 하나의 프로세스 내에서 스레드 간의 동기화
  • 프레임워크나 라이브러리 자체에서 제공
  • C언어는 없고 Java는 있음
교착 상태(Deadlock) 정의와 발생 조건, 해결 방법

교착 상태

  • 둘 이상의 프로세스/스레드가 자원을 점유한 상태에서 서로 다른 프로세스/스레드가 점유하고 있는 자원을 요구하며 무한정 기다리는 현상

발생 조건

-> 4가지 조건을 모두 만족해야 됨

  • 상호 배제: 하나의 프로세스/스레드가 자원에 접근할 수 있음
  • 비선점: 다른 프로세스/스레드의 자원을 뺏을 수 없음
  • 점유와 대기: 자원을 가진 상태에서 다른 자원을 기다림
  • 순환 대기: 순환 형태로 자원을 대기

해결 방법

  • 모든 프로세스가 lock을 잡는 순서를 동일하게 코딩
  • trylock을 활용하여 lock을 선점한 프로세스/스레드가 없을 때만 락을 얻으려고 시도하는 방법
  • 예방: 4가지 조건 중 1개 이상이 만족하지 않도록 함
    • 상호 배제 부정: 여러 프로세스가 공유 자원을 사용하도록 함
    • 점유와 대기 부정: 프로세스가 실행되기 전 필요한 모든 자원을 할당
    • 비선점 부정: 자원을 점유 중인 프로세스가 다른 자원을 요구할 때, 점유 중인 자원을 반납하고 대기
    • 순환 대기 부정: 자원에 고유한 번호를 할당하고, 번호 순서대로 자원을 요구하도록 함
  • 회피: 교착상태가 발생하지 않도록 알고리즘 작성
    • 은행원 알고리즘: 어떤 자원을 할당하기 전에 할당 후에도 안정 상태로 있을 수 있는지 검사 후 할당
  • 회복: 교착 상태 발생 후, 해당 프로세스를 종료하거나 할당된 자원을 해제 또는 선점하여 해결
    • 선점할 경우, 기아 상태가 발생하지 않도록 해야 함
  • 무시: 그냥 무시
기아 상태(Starvation) 정의와 해결방법

Starvation

  • 여러 프로세스가 부족한 자원을 점유하기 위해 경쟁할 때, 특정 프로세스에 영원히 자원 할당이 되지 않는 경우

해결 방법

  • 프로세스의 우선 순위 변경
  • 요청을 순서대로 처리하는 요청 큐 사용

식사하는 철학자 문제

5명의 철학자가 원형 식탁에서 식사를 한다. <br>
젓가락은 다섯개 뿐이며, 철학자는 반드시 두 젓가락이 있어야 식사를 할 수 있다. <br>
철학자는 반드시 자신의 왼쪽 또는 오른쪽에 있는 젓가락만 사용할 수 있으며, 식사를 마친 후에는 두 젓가락을 모두 내려놓는다. 

문제

  • 모든 사람이 왼쪽의 젓가락을 잡으면 교착상태 발생 -> 무한히 대기하다가 기아상태 발생

해결 방법

  • 최대 4명의 철학자만 테이블에 동시에 앉을 수 있도록 한다.
  • 한 철학자가 젓가락 두 개를 한번에 집을 수 있을 때만 집는다.
  • 비대칭 해결안을 사용. 홀수 번호의 철학자는 왼쪽을 먼저 집고 오른쪽을 집는다. 짝수 번호는 오른쪽을 먼저 집고 왼쪽을 집는다.
동기와 비동기 (Synchronous and Asynchronous)

동기

  • 요청에 대한 응답이 오면 다음 작업을 요청하는 것
  • 함수를 호출한 곳에서 호출된 함수가 결과를 반환할 때까지 대기 -> 작업 완료 여부를 계속 확인
  • 구성이 단순하나 멀티태스킹이 불가

비동기

  • 요청에 대한 응답을 기다리지 않고 다음 작업을 요청
  • 함수를 호출하는 곳에서 결과를 기다리지 않고 Callback 함수가 결과 처리 -> 작업 완료 여부를 확인하지 않음
  • 멀티태스킹이 가능하나 복잡도가 증가 (부하 컨트롤, 데이터 일관성 유지 등)

콜백 함수

  • OS가 실행하는 함수
  • 특정 이벤트가 발생하면 실행되는 함수
블락킹과 논블락킹

블락킹

  • 제어권이 호출된 함수로 이동 -> 호출된 함수의 작업이 끝나면 호출한 함수로 제어권 이동
  • 요청한 작업을 마칠 때까지 계속 기다림

논블락킹

  • 제어권이 호출한 함수에 있음 -> 작업의 완료 여부와 관계없이 새로운 작업 수행 가능
  • 요청한 작업을 즉시 마칠 수 없다면 즉시 리턴함
동기/비동기와 블락킹/논블락킹

동기/비동기

  • 애플리케이션에서 자주 다뤄지는 개념이며, 프로세스의 수행 순서 보장과 관련
  • 호출되는 함수의 작업 완료 여부를 누가 신경쓰느냐가 관심사
  • 비동기는 콜백으로 호출된 함수가 완료 여부를 신경쓰고 호출한 함수는 그냥 자기 일을 하다가 콜백을 받으면 됨

블락킹/논블락킹

  • 주로 IO, 멀티 스레딩에서 사용, 프로세스의 유휴 상태에 대한 개념
  • 호출되는 함수가 바로 return하느냐 마느냐가 관심사
CPU 스케줄링 알고리즘

SRT (Shortest Remaining Time)

  • 선점형 CPU 스케줄링 알고리즘
  • 남은 시간이 가장 적은 프로세스를 실행

Round Robin

  • 선점형 CPU 스케줄링 알고리즘
  • Time Slice 단위로 공평하게 프로세스 실행
  • 할당된 시간 내에 끝나지 않으면 다음 프로세스에게 CPU를 양보하고 준비 상태 큐의 가장 뒤로 배치

MLFQ (Multi Level Feedback Queue)

  • 선점형 CPU 스케줄링 알고리즘
  • 우선 순위 개수만큼 Queue가 있으며 최상위 순위의 Queue부터 실행 후 해당 큐의 할당량이 끝나면 하위 우선 순위 Queue를 실행하는 스케줄링 기법
  • 처음 시작은 모든 프로세스가 가장 높은 우선 순위 Queue에 존재하나 할당된 Time Slice를 소진하면 우선 순위를 감소시켜서 우선 순위 결정
  • Aging: 일정 주기마다 모든 작업을 가장 높은 우선 순위 큐로 이동시켜서 Starvation 방지
메모리 계층 구조

image

  • 레지스터: CPU 안에 있는 작은 메모리로 속도가 매우 빠르나 휘발성이 높고 용량이 매우 작음
  • 캐시: L1, L2, L3 캐시를 지칭하는데 레지스터 보다 정도가 낮지만 속도가 매우 빠르나 휘발성이 높고 용량이 매우 작음
  • 주기억장치: RAM을 지칭하는데 일반적인 속도와 휘빌성 그리고 적당한 용량을 가짐
  • 보조기억장치: HDD, SSD를 지칭하는데 비휘발성이고 속도가 느리고 용량이 많음
캐시 매핑

캐시 매핑

캐시가 히트되기 위해 매핑하는 방법

캐시 매핑 분류

  • 직접 매핑: 메모리가 1100이 있고 캐시가 110이 있다면 1:110, 2:120 같은 방식으로 매핑하는 것으로 처리가 빠르지만 충돌이 잦음
  • 연관 매핑: 순서를 일치시키지 않고 관련 있는 캐시와 메모리를 매핑하는 방법으로 충돌지 적지만 모든 블록을 탐색해야하여 속도가 느림
  • 집합 연관 매핑: 메모리가 1100이 있고 캐시 110이 있다면 캐시 15에는 메모리 150의 데이터를 무작위로 저장하는 것과 같은 방식으로 매핑하는 것으로 직접 매핑가 연관 매핑을 합쳐서 순서를 일치시키지만 집합을 둬서 저장하며 블록화하여 검색이 좀 더 효율적
캐시의 지역성
  • 시간 지역성: 최근에 참조된 주소가 다시 참조되는 특성 (순환, 재귀)
  • 공간 지역성: 참조된 주소와 인접한 주소가 다시 참조되는 특성 (배열)
가상 메모리

image

가상 메모리

  • 물리 메모리 크기의 한계를 극복하기 위해 나온 기술로 메모리가 실제 메모리보다 많아 보이게 하는 기술
  • 프로그램에 실제 메모리 주소가 아닌 가상의 메모리 주소를 주는 방식으로 프로그램 별로 사용 중인 메모리보다 큰 메모리를 사용하는 듯한 환상을 주는 기법
  • MMU(Memory Management Unit)는 가상 메모리 주소를 물리 주소로 변환

가상 메모리 사용 시 장점

  • 실제 프로그램 전체를 적재하여 사용하지 않고 일부분만 적재하기 때문에 메모리 제약을 극복
  • 메모리의 실제 주소를 사용하지 않으므로 보안 상의 장점이 존재
세그멘테이션
  • 메모리에 불연속적으로 할당하는 방법 중 하나로 프로세스를 서로 다른 크기의 논리적 단위인 세그먼트로 나누어 메모리에 배치하는 것
  • 메모리를 세그먼트로 나누고 세그먼트 테이블에 각 세그먼트의 시작(base) 주소크기(limit) 정보를 운용하여 가상 메모리를 관리하는 기법
  • 작은 메모리가 중간 중간 존재하여 총 메모리는 충분하지만 실제로는 할당할 수 없는 상황인 외부 단편화가 발생할 수 있음
페이징
  • 메모리에 불연속적으로 할당하는 방법 중 하나로 프로세스를 일정 크기인 페이지로 잘라서 가상 메모리에 적재하고 페이지 테이블을 이용하여 프레임으로 변환하여 가상 메모리를 관리하는 기법
  • 현대 운영체제에서 사용되는 메모리 할당 기법
  • CPU가 가상 주소 접근 시 MMU가 페이지 테이블의 시작(base) 주소에 접근해서 물리주소 가져옴
  • 메모리를 할당할 때 프로세스가 필요한 양보다 더 큰 메모리가 할당되어서 프로세스에서 사용하는 메모리 공간이 낭비 되는 현상인 내부 단편화가 발생할 수 있음
  • 페이지: 가상 메모리를 최소 단위로 쪼개어 만든 일정한 크기의 블럭
  • 프레임: 물리 메모리에 페이지 크기와 같은 블럭으로 나눈 블럭
페이지 테이블, TLB (Translation Lookaside Buffer)

요약

  • 가상 주소로 물리 주소에 접근할 때, TLB -> 페이지 테이블 -> Disk 순으로 접근

과정

  • MMU는 TLB 캐시를 저장해 가상주소가 물리 주소로 변환되어야할 때, TLB에서 먼저 검색
  • 해당 주소가 있다면: TLB Hit -> 물리 주소가 반환되고 메모리에 접근
  • 해당 주소가 없다면: TLB Miss -> 페이지 테이블에서 페이지와 프레임의 맵핑 탐색
  • 해당 주소가 있다면: 페이지 테이블 Hit -> 이 값을 다시 TLB에 쓰고 물리 주소로 변환 후 메모리에 접근
  • 해당 주소가 없다면: Page Fault -> Disk에서 찾아 이 값을 페이지 테이블과 TLB에 쓰고 물리 주소로 메모리에 접근
페이지 교체 알고리즘

FIFO

  • 들어온 페이지 순서대로 페이지를 교체하는 알고리즘
  • Belady의 모순 발생: 페이지 프레임의 개수를 늘리면 Page Fault 발생이 감소할 것 같으나, 실제로는 실패가 증가할 수도 있음

LRU (Least-Recently-Used)

  • 가장 오랫동안 사용되지 않은 페이지를 선택하여 교체하는 알고리즘

LFU (Least-Frequently-Used)

  • 참조 횟수가 가장 적은 페이지를 교체하는 알고리즘
컴퓨터가 부팅되는 과정
  • 처음에 부팅이 되면 BIOS가 실행 될 수 있도록 메모리의 0번지에는 ROM이 올라와있고, CPU는 0번지를 읽어 자동으로 ROM의 BIOS가 실행
  • BIOS는 하드디스크의 0번지 부터 한 섹터를 읽어와 거기에 있는 부트스트랩 코드를 실행
  • 부트스트랩이 부트로더(bootcamp, grub)를 실행시키고 그 다음 커널이 로드
심볼릭 링크와 하드 링크의 차이
  • 심볼릭 링크(소프트 링크): 원본 파일의 이름을 가리키는 링크, 원본 파일이 사라지면 역할 수행X
  • 하드 링크: 원본 파일의 이름을 가리키는 링크, 사본을 생성, 원본파일이 사라져도 원본과 동일한 내용의 파일을 가질 수 있음을 의미
컴파일러와 인터프리터의 차이

컴파일러

  • 프로그램 전체를 한 번에 번역
  • 목적 프로그램 생성: 목적 프로그램(기계어)으로 번역 -> 링킹 -> 실행 가능한 실행파일(어셈블리, 바이너리 파일) 생성
  • 번역 속도 느림, 실행 속도 빠름
  • C, Java

인터프리터

  • 프로그램을 한 줄씩 번역
  • 번역과 동시에 프로그램 실행
  • 번역 속도 빠름, 실행 속도 느림
  • Python