본문 바로가기
Book/IT Detail

운영체제

by 코젼 2024. 9. 12.
728x90
반응형

목차

    운영체제

    • 하드웨어 위에 설치되어, 하드웨어 계층과 소프트웨어 계층을 연결하는 소프트웨어 계층이다.
    • CPU, 메모리의 자원은 한정적이므로, 자원을 관리한다.
    • MacOS, Windows, Linux, Unix 등이 있다.

    운영체제의 목적 

    • 처리 능력(throughput) 향상: 자원 관리를 통해 시스템 처리 능력을 향상시킨다.
    • 반환 시간(turnaround time) 단축: 사용자가 시스템에 요청한 작업을 완료할 때까지 걸리는 시간
    • 사용 가능도(availability) 향상
    • 신뢰도(reliability) 향상

    CPU와 메모리 구조

    • CPU(Central Processing Unit) == 프로세서(processor)
      • CPU는 하나의 프로세스만 처리할 수 있어서,
        멀티 프로세스 환경에서 OS가 스케줄링을 통해 CPU에 프로세스를 할당한다.
      • 프로세스: 메모리에 로드한 프로그램. CPU가 처리한다.
    • 프로그램을 실행하는 데 필요한 연산을 처리하고 수행한다.
    • 메모리: 데이터를 저장하기 위한 기억장치
      • 주 기억장치(휘발성) - RAM
      • 보조 기억장치(비휘발성) - SSD, HDD

    메모리의 계층 구조

    • 레지스터: CPU 내부에 존재하며, 필요한 데이터를 임시로 저장한다.
    • 캐시: CPU 내부에 존재하며, CPU와 RAM 사이의 속도 차이를 해결하기 위한 기억장치다.

    커널과 시스템 콜

    • 커널: OS의 핵심 요소
      • 컴퓨터 하드웨어와 프로세스의 보안, 자원 관리, 하드웨어 추상화 등...
      • 자원 관리: CPU 스케줄링, 메모리 관리, 입출력 관리, 파일 시스템 관리 등...

    커널의 위치

    • 커널 모드: 하드웨어에 직접 접근해서 메모리, CPU 자원을 사용한다.
    • 사용자 모드: 직접 접근 불가해서 시스템 콜(system call) 을 통해 커널에 요청한다.
      • 사용자 모드에서 시스템 콜을 통해 커널 모드에 접근해서 필요한 기능을 수행한다.
      • wait(): 부모 프로세스가 자식 프로세스의 수행을 기다림
      • fork(): 프로세스 생성
        • 새로운 프로세스는 기존 프로세스에서 fork() 함수를 통해 생성한다.
        • 함수를 호출한 프로세스를 복사하는 기능이 있다.
        • 기존 프로세스는 부모 프로세스가 되고, 새로운 프로세스(복사된 프로세스)는 자식 프로세스가 된다.
        • 부모 프로세스에서 fork() 함수를 호출하면, 부모 프로세스는 자식 프로세스의 PID 값을, 자식 프로세스는 0을 반환한다.

    부모 프로세스가 자식 프로세스를 종료시킬 수 있는 조건

    • 자식 프로세스가 할당된 자원을 초과해 사용할 때
    • 자식 프로세스에 할당된 작업이 없을 때
    #include <stdio.h>
    #include <unistd.h>
    
    int main() {
    	printf("start!\n"); //부모 프로세스
        int forkRet = fork(); //fork() 함수 호출
        if (forkRet == 0) { //3. 출력
        	printf("child process %d\n", getpid());
        } else { //1. 부모 프로세스는 0을 반환하지 않는다.
        	printf("forkRet:%d parent process:%d\n", forkRet, getpid());
        }
        return 0; //2. 복사된 자식 프로세스는 0을 반환한다.
    }
    //출력
    start!
    forkRet:136 parent process:135
    child process 136

    시스템 콜에서 커널에 매개변수를 전달하는 방법

    • CPU의 레지스터에 직접 전달(매개변수 개수 > 레지스터의 개수 문제됨)
    • 매개변수를 메모리에 저장한 후, 메모리의 주소 값을 레지스터에 저장
    • 매개변수를 프로그램의 stack 에 push 하고, OS 에서 pop 해서 매개변수를 전달

    프로세스

    프로세스와 스레드

    프로세스

    • 프로세스(process): 실행 중인 하나의 프로그램을 의미한다.
    • 프로그램: 특정 작업을 시작하기 위한 명령어의 집합

    운영체제가 프로세스를 종료하는 경우

    • exit() 를 호출해 정상적으로 종료하는 경우
    • 프로세스의 실행 시간 또는 특정 이벤트 발생을 기다리는 시간이 제한된 시간을 초과한 경우
    • 파일 검색 또는 입출력에 실패한 경우
    • 오류가 발생하거나 메모리 부족 등이 발생한 경우

    순서

    • OS프로그램을 시작하면서, 디스크에 저장된 데이터를 메모리로 로드한다.
    • 프로세스는 OS로부터 독립된 메모리영역을 할당받는다. (코드, 데이터, 스택, 힙)

    프로세스의 메모리 영역 구조

    스택 영역과 힙 영역은 동적으로 메모리 할당이 가능해 두 영역 사이에 빈 메모리 공간이 존재한다.

    메모리 영역을 공유한다.

    - 스택 오버플로(stack overflow): 스택이 힙 영역 침범

    - 힙 오버플로(heap overflow): 힙이 스택 영역 침범

    1. 스택(stack): 높은 주소 -> 낮은 주소로 메모리가 할당되며, 영역 크기는 컴파일 때 결정된다. (LIFO, 후입선출)
    2. 힙(heap): 낮은 주소 -> 높은 주소로 메모리가 할당되며, 영역 크기는 런타임 때 결정된다. (FIFO, 선입선출)
    3. 데이터(data): BSS 영역 / 데이터 영역
      • BSS 영역: 초기화 하지 않은 변수
      • 데이터 영역: 초기화 한 변수
    4. 코드(code): 기계어로 컴파일되어 저장되는 영역, 텍스트 영역이라고도 한다.

    스레드

    • 프로세스에서 실제로 실행되는 흐름의 단위를 말한다.
    • 프로세스는 한 개 이상의 스레드를 가진다.
    • 메모리 공간을 이용한다.
    • 스택 영역을 할당받는다.
    • 영역은 다른 스레드와 공유한다.
    • 사용자 레벨 스레드(user-level-thread): 사용자가 라이브러리를 이용해 생성 및 관리
    • 커널 레벨 스레드(kernel-level thread): 커널이 스레드를 생성 및 관리

    모델

    • 사용자 레벨 스레드(N) : 커널 레벨 스레드(1)
      • 사용자 레벨에서 스레드를 관리한다.
      • 시스템 콜을 호출할 경우, 나머지 N-1 개는 커널 레벨에 접근할 수 없으므로 멀티 코어의 병렬성을 이용할 수 없다.
    • 사용자 레벨 스레드(1) : 커널 레벨 스레드(1)
      • 사용자 레벨 스레드 수만큼 커널 레벨 스레드가 생성되므로 성능 저하가 일어날 수 있다.
    • 사용자 레벨 스레드(N) : 커널 레벨 스레드(M)
      • N < M 여야만 하고, 구현이 어렵다.

    PCB(Process Control Block)

    • 프로세스 정보를 가지고 있다.
      • 프로세스의 현재 상태, 프로세스를 나타내는 고유의 PID(Process ID),
        부모 프로세스 PID, 자식 프로세스 PID, 다음 실행할 명령어의 주소(Program Counter),
        프로세스의 우선순위, 메모리 제한 등...
    • OS는 프로세스를 제어하기 위해 프로세스 정보를 PCB 에 저장한다.

    프로세스 상태도

    • 모든 프로세스는 CPU 에 의해 생성되고 소멸하는 과정을 거친다.
    • 생성(new), 준비(ready), 대기(waiting), 실행(running), 종료(terminated)

    프로세스 상태도

    • 생성(new): 프로세스가 PCB를 가지고 있지만 OS로부터 승인(admit) 받기 전
      • 승인(admit): CPU를 제외한 다른 자원이 준비되어 해당 프로세스가 준비 상태가 될 수 있도록 OS 가 허락하는 것
    • 준비(ready): OS로부터 승인받은 후 준비 큐에서 CPU 할당을 기다림
    • 실행(running): 프로세스가 CPU를 할당받아 실행함
    • 대기(waiting): 프로세스가 입출력이나 이벤트 발생을 기다려야 해서 CPU 사용을 멈추고 기다림
    • 종료(terminated): 프로세스 실행을 종료함

    프로세스 상태 변화

    • 생성 -> 준비: 생성 상태의 프로세스가 OS로부터 승인을 받아, 준비 상태의 프로세스가 모여있는 자료구조인 준비 큐에 추가됨
    • 준비 -> 실행: 준비 큐에 있는 프로세스 중 우선순위가 높은 프로세스가 디스패치되어 실행됨
      • 디스패치(dispatch): 프로세스에 CPU 자원을 할당해서 실행 상태로 변경되는 것
    • 실행 -> 준비: CPU 독점을 방지하기 위해 타임아웃되어 준비 상태로 변경됨
    • 실행 -> 대기: 입출력 또는 이벤트 때문에 대기 상태로 변경됨
    • 대기 -> 준비: 입출력 또는 이벤트가 완료되어 준비 상태로 변경됨
    • 실행 -> 종료: 실행 중인 프로세스가 정상적으로 끝나서 종료 상태로 변경됨

    멀티 프로세스와 멀티 스레드

    • 동시성(concurrency): CPU가 싱글 코어일 때, 여러 작업을 번갈아가면서 처리하는 방식
      • 콘텍스트 스위칭(context switching): 처리 중인 작업 교체
    • 병렬성(parallelism): CPU가 멀티 코어일 때, 각 CPU에서 각 작업을 동시에 처리하는 방식

    • 멀티 프로세스(multi process): 응용 프로그램(1): 프로세스(n)
      • 한 프로세스가 죽어도 다른 프로세스에 영향을 주지 않는다.
      • 여러 프로세스를 하나의 CPU가 처리해야하기 때문에 콘텍스트 스위칭 작업이 필요하다.
        • 멀티 프로세스를 처리하기 위해 CPU 스케줄러에 의해 인터럽트가 발생하면서 콘텍스트 스위칭이 이루어진다.
      • IPC(Inter Process Communication) 을 통해 프로세스 공유 자원을 공유해야 한다.
        • 직접 참조하는 것보다 비효율적이다.
      • 장점: 응용 프로그램을 멀티 프로세스로 구성하면 안정적이다.
      • 단점: 시간과 메모리 공간을 많이 사용한다. (오버헤드(overhead))
        • 오버헤드 발생 예시
          • P1 -> P2 순서일 때, P1 에서 인터럽트 발생하는 경우
            • P1 정보를  P1 PCB에 저장
            • P2 PCB에 저장된 정보 로드
          • 처리하는 중에 CPU는 아무 일도 못하게 된다.
          • 어떤 처리를 하는 데 간접적인 처리 시간과 메모리가 소요될 경우 '오버헤드가 발생한다' 라고 한다.
    • 멀티 스레드(multi thread): 여러 개의 스레드가 각자 다른 작업을 처리한다.
      • 스레드 간 코드, 데이터, 힙 영역을 공유한다.
        • PCB에 프로그램 카운터와 스택 포인터 값이 저장되어 있다.
          • 프로그램 카운터(PC, Program Counter): 프로세스가 이어서 처리해야 하는 명령어의 주소 값
          • 스택 포인터(stack pointer): 스택 영역에서 데이터가 채워진 가장 높은 주소 값
      • 콘텍스트 스위칭할 때 오버헤드가 적게 발생하고, IPC를 사용하지 않아도 된다.
      • 프로세스 간 자원 공유보다 시스템 처리 비용이 적고 프로그램 응답 시간도 단축된다.
      • 스택 영역을 다른 스레드와 함꼐 사용하므로, 공유 자원에 대한 동기화가 필수다.
      • 스레드에 문제가 생기면 프로세스 내 다른 스레드에 영향을 미칠 수 있다.

    멀티 스레드

    콘텍스트 스위칭

    • 인터럽트(interrupt): 입출력 관련 이벤트가 발생하거나 예외 상황이 발생할 때, 이에 대응할 수 있게 CPU 에 처리를 요청하는 것
      • 입출력이 발생했을 때, CPU 사용 시간이 만료되었을 때, 자식 프로세스를 생성할 때 등...
    • 콘텍스트(context): CPU가 처리하는 프로세스의 정보

    프로세스 동기화

    • 경쟁 상태(race condition): 공유 자원동시에 접근해 경쟁하는 상태
      • 여러 프로세스 또는 스레드에서 하나의 공유 자원에 접근하는 경우, 접근 순서에 따라 결과 값이 달라질 수 있다.
      • 스레드 안전하지 않은 상태
    • 임계 영역(critical section): 공유 자원에 접근할 수 있고, 접근 순서에 따라 결과가 달라지는 코드 영역
    1. A가 냉장고에 우유가 없는 것을 확인했다.
    2. A가 우유를 사러 마트에 갔다.
    3. B가 냉장고에 우유가 없는 것을 확인했다.
    4. B가 우유를 사러 마트에 가는 도중, A가 우유를 사왔다.
    5. B가 우유를 사왔다.
    
    우유의 개수는 0 -> 1개여야 하는데,
    0 -> 2개가 되는 결과를 가져왔다.
    
    임계 영역: 냉장고에 우유 유무를 판단하고 우유를 추가하는 부분

    뮤텍스

    • 뮤텍스(mutex): (lock)을 가진 프로세스만이 공유 자원에 접근할 수 있게 하는 방법
    • 락킹 매커니즘(locking mechanism): 임계 영역에 접근한 프로세스가 임계 영역에 락을 거는 행위
    • 바쁜 대기(busy waiting): 프로세스가 공유 자원에 접근할 수 있는 권한을 얻을 때까지 확인하는 과정
      • 스핀락(spinlock): 락을 얻기 위해 프로세스가 반복문을 돌면서 기다리는 것
        • 프로세스가 대기 상태가 되지 않으므로, 프로세스가 빠르게 교체될 수 있다.
    1. 식당에는 화장실 1칸, 화장실 문을 열 수 있는 열쇠 1개가 있다.
    2. A가 열쇠를 가지고 화장실에 간다. - 락킹 매커니즘
    3. B는 열쇠가 없기 때문에 기다리면서 열쇠가 있는지 계속 확인한다. - 바쁜 대기(스핀락)
    4. A가 열쇠를 식당에 반납하면, B가 화장실에 간다.
    
    임계 영역: 화장실(공유 자원)
    프로세스: A, B
    락: 열쇠

     

    세마포어

    • 세마포어(semaphore): 공유 자원에 접근할 수 있는 프로세스의 수를 정해 접근을 제어하는 방법
    • 시그널링 매커니즘(signaling mechanism): 공유 자원에 접근한 프로세스가 접근을 해제하면, 다른 프로세스가 접근할 수 있도록 신호를 보낸다.
    1. 식당에는 화장실 3칸, 화장실 문을 열 수 있는 열쇠 3개가 있다.
    2. A가 열쇠를 가지고 화장실에 간다. 열쇠는 2개가 남는다.
    3. B, C는 열쇠를 하나씩 가지고 화장실에 간다.
    4. D는 열쇠가 없어서 화장실에 가지 못한다. - 기다리지도 않음
    5. C가 열쇠를 식당에 반납하면, 식당 주인이 열쇠가 있다고 D에게 알려주고, D가 화장실에 간다. - 시그널링 매커니즘
    
    임계 영역: 화장실(공유 자원)
    프로세스: A, B, C, D
    프로세스 수를 제어하기 위한 정수 변수: 열쇠

    작업 순서

    • 동기(synchronization): 여러 작업을 처리할 때 작업 순서를 보장함
    • 비동기(asynchronization): 여러 작업을 처리할 때 작업 순서를 보장하지 않음

    작업을 위한 대기 구분

    • 블로킹(blocking): 작업을 수행할 때 대기할 수 있고, 작업 순서를 보장하지 않음
    • 넌블로킹(non-blocking): 작업을 시작하면 대기 없이 수행함

    교착 상태

    • 교착 상태(deadlock): 상호배제 기법 때문에 2개 이상의 프로세스가 각각 자원을 가지고 있으면서 서로의 자원을 요구하며 기다리는 상태
    • 교착 상태가 발생하는 필요 충분 조건 
      • 상호배제(mutual exclusion): 하나의 공유 자원에 하나의 프로세스만 접근할 수 있다. 공유 자원(1) : 프로세스(1)
      • 점유와 대기(hold and wait): 프로세스가 최소 하나의 자원을 가지고 있으면서, 추가로 다른 프로세스에서 사용 중인 다른 자원을 점유하기 위해 대기한다.
      • 비선점(non-preemption): 다른 프로세스에 할당된 자원을 뺏을 수 없다.
      • 환형 대기(circular wait): 프로세스가 자신의 자원을 점유하면서, 이나 에 있는 프로세스의 자원을 요구한다.
    • 교착 상태 방지
      • 상호배제 부정: 여러 프로세스가 동시에 하나의 공유 자원에 접근할 수 있게 한다. 공유 자원(1) : 프로세스(n)
      • 점유와 대기 부정: 프로세스가 자원을 점유하지 않은 상태에서만 자원을 요구할 수 있거나, 프로세스가 실행되기 전 모든 자원을 할당하게 해서 대기를 없앤다.
      • 비선점 부정: 다른 자원을 요구하려면 점유한 자원을 반납한다.
      • 환형 대기 부정: 자원을 선형 순서로 정렬고유 번호를 할당한다. 프로세스에서 요구할 수 있는 번호의 방향을 정해서 한 쪽 방향으로만 자원을 요구하게 한다.

    스레드 안전

    • 스레드 안전(thread safe): 멀티 스레드 환경에서 하나의 변수, 함수, 객체에 스레드 여러 개가 동시에 접근해도 문제가 없다는 것을 의미한다.

    스레드 안전하지 않은 상태

    스레드 안전을 위한 조건

    • 상호 배제(mutual exclusive): 공유 자원에 접근해야 할 때, 뮤텍스 또는 세마포어와 같은 상호배제 기법 사용으로 접근 통제
    • 원자 연산(atomic operation): 연산 진행O, X 를 통해, 연산 도중에는 다른 스레드가 접근할 수 없게 한다.
    • 재진입성(reentrancy): 특정 함수를 실행 중일 때, 다른 스레드가 동일한 함수를 실행해도 각 스레드에 올바른 결과가 나와야 한다.
    • 스레드 지역 저장소(thread local storage): 각 스레드에서만 접근할 수 있는 저장소를 사용해서 공유되는 자원을 줄인다.

    IPC

    • IPC(Inter Process Communication): 프로세스 간 자원을 공유하는 방식
      • 프로세스는 고유한 메모리 영역을 갖기 때문에 프로세스 간 자원을 공유해야 한다.

    종류

    • 공유 메모리(shared memory): 공유 가능한 메모리 구성
      • 여러 프로세스에서 접근할 수 있으므로 동기화 문제가 발생할 수 있다.
    • 소켓(socket): 네트워크 소켓을 이용하는 프로세스 간 통신
      • 외부 시스템과 이용 가능
      • 클라이언트(client), 서버(server) 구조
    • 세마포어(semaphore): 접근하는 프로세스를 제어해 공유 자원 관리
    • 파이프(pipe): FIFO(First in First Out) 단방향 통신 지원(읽기 or 쓰기 가능)
      • 양방향 통신을 위해서 읽기 파이프, 쓰기 파이프를 각각 생성해야 한다.
    • 메시지 큐(message queue): FIFO 자료 구조

    좀비 프로세스와 고아 프로세스

    • 좀비 프로세스(zombie process): 자식 프로세스가 종료되었지만, 부모 프로세스가 자식 프로세스를 회수하지 않아 남겨진 자식 프로세스
      • 자식 프로세스가 종료될 때, 부모 프로세스에 SIGCHID 시그널을 보낸다.
      • 부모 프로세스에서 wait() 함수(시스템 콜)를 호출해 자식 프로세스의 상태 정보를 받고 자원을 회수한다.
      • 자원 회수에 실패할 경우, 좀비 프로세스가 된다.
      • 좀비 프로세스가 많아질 경우, 자원이 낭비된다.
    • 고아 프로세스(orphan process): 부모 프로세스가 자식 프로세스보다 먼저 종료되는 경우, 남겨진 자식 프로세스
      • 자식 프로세스의 부모 PIDinit 프로세스(부팅 시 가장 먼저 실행되는 프로세스)의 PID인 1로 변경한다.
      • 고아 프로세스의 부모 프로세스 == init 프로세스
      • 고아 프로세스가 종료하면 init 프로세스가 자원을 회수해서 좀비 프로세스가 되는 것을 막을 수 있다.

    스케줄링

    스케줄링의 목적

    • 멀티 프로세스 환경에서 모든 프로세스를 공평하게 실행하는 것
    • 공평성: 특정 프로세스가 실행되지 않는 경우가 없도록 할 것
    • 효율성: 자원이 사용되지 않는 시간이 없도록 할 것
    • 안정성: 우선순위의 프로세스를 먼저 처리할 것
    • 반응 시간 보장: 일정 시간 내에 응답해야 한다. (프로세스가 오랫동안 응답이 없으면 사용자는 시스템이 멈춘 것으로 본다.)
    • 무한 연기 방지: 프로세스 처리가 무한히 연기되지 않도록 할 것

    스케줄링의 단계

    • 장기 스케줄링(long-term scheduling):
      • 준비 큐에 어떤 프로세스를 넣을지 결정해 메모리에 올라가는 프로세스 수를 조절한다.
      • 현대 운영체제에서는 시분할 시스템을 사용해서 대부분 사용하지 않는다.
      • == 잡 스케줄링(job scheduling), 승인 스케줄링(admission scheduling)
    • 중기 스케줄링(mid-term scheduling): 메모리에 로드된 프로세스 수를 동적으로 조절한다.
      • 스왑 아웃(swap out): 메모리에 프로세스가 많이 로드되면, 일부 프로세스를 통째로 저장한다.
        • 중단 상태(suspended): 스왑 아웃당한 프로세스
          • 중단된 준비 상태: 준비 상태에서 스왑 아웃
          • 중단된 대기 상태: 대기 상태에서 스왑 아웃
      • 스왑 인(swap in): 스왑 아웃한 프로세스에서 이벤트 요청이 오면 통째로 다시 메모리에 로드한다.
      • 스와핑(swappint): 스왑 아웃, 스왑 인처럼 프로세스를 통째로 메모리 영역과 저장 공간으로 옮기는 것
        • 메모리 공간보다 많은 프로세스를 실행할 수 있다.
    • 단기 스케줄링(short-term scheduling): 스케줄링 알고리즘을 통해 준비 큐에 있는 대기 상태 프로세스 중 어떤 프로세스를 실행할지 결정한다. 디스패치 할 대상 선정

    스케줄링의 단계
    스케줄러 관점에서 스케줄링

    스케줄링 알고리즘

    • CPU 스케줄러(단기 스케줄러)가 준비 큐에 있는 프로세스 중 어떤 프로세스를 실행시킬지(dispatch) 결정하는 데 사용한다.
    • CPU 사용률, 처리량, 응답 시간, 반환 시간, 대기 시간 중 어떤 기준을 더 중요하게 여길지 판단하며 결정한다.
    프로세스 이름 예상 실행 시간 준비 큐에 들어온 시간
    P1 150 0
    P2 60 20
    P3 300 40
    P4 270 60
    P5 120 80

    비선점형 스케줄링

    • 실행 중인 프로세스가 종료될 때까지 다른 프로세스를 실행할 수 없다.
    • FCFS(First Come First Served) 스케줄링: 준비 큐에 먼저 들어온 프로세스가 우선순위를 가진다.
      • 평균 대기 시간: 290
      • {0 + (150 - 20) + (210 - 40) + (510 - 60) + (789 - 80)} / 5
        • P1 - P2 - P3 - P4 - P5
    • SJF(Shortest Job First) 스케줄링: CPU를 점유하는 실행 시간이 짧은 프로세스가 우선순위를 가진다.
      • 평균 대기 시간이 가장 짧지만, 실행 시간이 긴 프로세스는 실행 시간이 짧은 프로세스에 밀려 기아 상태가 될 수 있다.
      • 기아 상태(starvation): 우선순위가 높은 프로세스만 실행돼서 우선순위가 낮은 프로세스는 실행되지 않는 상태
      • 평균 대기 시간: 218
      • {0 + (150 - 20) + (600 - 40) + (330 - 60) + (210 - 80)} / 5
        • P1 - P2 - P5 - P4 - P3

    선점형 스케줄링

    • 스케줄러가 실행 중인 프로세스를 중단시키고 다른 프로세스를 실행할 수 있다.
    • RR(Round Robin) 스케줄링: 우선순위가 없고, 모든 프로세스를 순서대로 일정 시간 동안 실행한다.
      • 단점: 콘텍스트 스위칭이 빈번하게 일어나서 오버헤드가 크다.
      • 장점: 모든 프로세스가 반복 수행되어 응답 속도가 빠르다.
      • 대기 최대 시간: 200밀리초 (전체 프로세스 수 -1) * (시간 단위)
        • 시간 단위를 50이라고 가정한 경우지만, 콘텍스트 스위칭이 빈번해 시간 단위를 적절하게 설정해야 한다.
    • SRTF(Shortest Remaining Time First) 스케줄링: 대기 시간이 가장 짧게 남은 프로세스를 우선 수행한다.
      • 더 짧은 대기 시간을 가진 프로세스가 큐에 들어오면 CPU를 차지한다.
      • 평균 대기 시간이 짧지만, 수행 시간이 긴 프로세스는 기아 상태가 될 수 있다.
      • 평균 대기 시간 = 202
        • {(200 - 20) + (20 - 20) + (600 - 40) + (330 - 60) + (80 - 80)} / 5
          • P1 - P1중단 - P2 - P5 - P1 - P4 - P3 
    • 멀티 레벨(multi level) 스케줄링: 목적에 따라 여러 개로 분리해 사용하는 알고리즘
      • 분리한 큐는 각각 우선순위가 있고, 각자 다른 스케줄링 알고리즘을 적용할 수 있다.
        • foreground 큐: 응답 속도가 중요한 프로세스가 들어간다.
        • background 큐: 성능을 중요시하는 프로세스가 들어간다.

    메모리 관리 전략

    논리 메모리와 물리 메모리

    • 논리 메모리 영역(logical memory address space): 프로세스가 보는 메모리 영역
      • == 가상 메모리 영역(virtual memory address space)
    • 물리 메모리 영역(physical memory address space): 실제로 사용되는 메모리 영역(RAM)

    CPU가 프로세스를 실행할 때 사용하는 주소 값과 실제 주소 값이 다르므로 변환 필요

    • 메모리 관리 장치(MMU, Memory Managment Unit): 논리 주소 -> 물리 주소 변환 장치
      • CPU에 위치한다. 
      • 논리 주소(logical address): CPU가 프로세스를 실행하여 보는 주소 값
      • 물리 주소(physical address): 실제 메모리에서 사용되는 주소

    연속 메모리 할당

    • 연속 메모리 할당(contiguous allocation): 멀티 프로세스 환경에서 여러 프로세스를 메모리에 연속적으로 로드하는 방법

    고정 분할 방식

    • 고정 분할 방식: 메모리 영역을 분할한 후, 각 영역에 프로세스 할당
      • 분할 크기는 다를 수 있으며, 분할된 크기는 고정된다.
      • 메모리에 올릴 수 있는 프로세스 수와 크기가 제한되어 있다.
      • 단편화(fragmentation) 문제가 발생할 수 있다.
    56MB 를 고정 분할 방식을 사용하면 8MB 의 7개로 나눌 수 있다.
    
    2MB 메모리 공간을 합치면 10MB 가 되므로 할당할 수 없다.
      -- 외부 단편화(external fragmentation)
        -- 해결: 메모리 압축(memory compaction) - 프로세스가 사용 중인 메모리 공간을 재배치해서
                흩어져있는 가용 메모리 공간을 하나로 합치는 것
    기준은 8MB 인데, 8MB보다 작은 메모리 공간이 할당될 경우 2MB 메모리 공간의 손실이 일어난다. 
      -- 내부 단편화(internal fragmentation)

    가변 분할 방식

    • 할당할 프로세스의 크기에 따라 메모리 공간을 분할한다.
    • 메모리 할당 알고리즘
      • 최초 적합(first-fit): 프로세스 크기만큼 비어있는 메모리 공간에 차례대로 프로세스 로드
      • 최적 적합(best-fit): 가장 작은 공간에 프로세스 할당(메모리 공간 모두 탐색 필요)
      • 최악 적합(worst-fit): 가장 큰 공간에 프로세스 할당(메모리 공간 모두 탐색 필요)

    비연속 메모리 할당

    • 프로세스의 메모리 영역을 나눠서 메모리 공간에 저장하는 방법

    페이징

    • 페이징(paging) 기법: 프로세스의 논리 메모리 영역물리 메모리 영역을 각각 일정한 크기페이지(page) 와 프레임(frame) 으로 나눈다.
      • 페이지 테이블(page table): 프로세스의 페이지 정보, 페이지에 매핑하는 프레임의 주소 값을 저장한다.
        • 페이지와 프레임에는 각각 번호가 할당되어 있어, 프로세스의 페이지메모리의 프레임을 매핑한다.
        • 각 프로세스의 PCB 에 저장된다.
        • 페이지 테이블을 저장하기 위한 추가적인 메모리 공간이 필요하다.
      • 물리 메모리에 연속적으로 할당할 필요가 없어 외부 단편화 문제를 해결할 수 있다.
      • 프로세스 크기가 페이지 수로 나누어 떨어지는지는 보장하지 않기 때문에, 내부 단편화가 발생할 수 있다.

    페이징 기법

    • 계층적 페이징(hierarchical paging): 페이지 테이블을 다시 페이지로 나눠 테이블 자체를 페이징한다.
      • == 멀티 레벨 페이징(multi-level paging)
    • 해시 페이지 테이블(hashed page table): 해시 테이블의 각 항목에 저장된 연결 리스트에 페이지 번호를 해싱(hashing)한 뒤에 첫 번째 요소와 가상 페이지 번호를 비교하는 방식이다.
    • 역 페이지 테이블(inverted page table): 프레임을 이용해 페이지를 찾는다.

    세그먼테이션

    • 세그먼테이션(segmentation): 프로세스의 메모리 영역을 논리적 단위인 세그먼트로 분할해 메모리를 할당한다.
      • 논리적 단위: 파일 내 함수 단위, 프로세스의 스택, 힙과 같은 영역을 의미하기도 한다.
      • 세그먼테이션 테이블(segment table): 세그먼트 논리 주소물리 주소로 매핑한다.
        • 세그먼트 번호(인덱스), 세그먼트별 시작 주소 base, 세그먼트 길이 limit 저장
      • 단위별로 데이터를 보호하기 쉽다.
      • 세그먼트의 크기가 균등하지 않아서 프로세스 할당/해제 반복 과정에서 외부 단편화 문제가 발생할 수 있다.
      • 메모리에 로드된 스택 세그먼트 영역에서 오버플로가 발생하면 다른 프로세스와 메모리 영역이 겹칠 수 있다.
        • 다른 프로세스의 세그먼트나 스택 오버플로가 발생한 세그먼트를 디스크로 스압 아웃해야 한다.

    가상 메모리

    • 가상 메모리(virtual memory): 프로세스의 일부만 메모리에 로드하고, 나머지는 디스크에 둔 상태로 프로세스를 실행하는 방식
      • 더 많은 프로세스를 메모리에 로드할 수 있다.
      • 프로그램이 메모리 크기에 대한 제약 받을 수 있다.
      • 동시에 많은 프로그램을 실행하므로 CPU 이용률처리율을 높일 수 있다.
      • 필요한 영역만 메모리에 로드해 스와핑 횟수를 줄여서 프로그램 실행 속도를 높일 수 있다.

    요구 페이징

    • 요구 페이징(demand paging): 프로세스에서 필요한 페이지만 메모리에 로드하는 방식
      • 필요하지 않은 페이지는 디스크에 저장하고, 요청이 올 때만 메모리에 로드한다.
      • 페이지 폴트(page fault): 물리 메모리에 필요한 페이지가 없을 때
        • 발생 시, 디스크에서 필요한 페이지를 스왑 인한다.
        • 페이지에 해당하는 메모리 영역이 물리 메모리에 존재하는지는 페이지 테이블에서 확인할 수 있다.
          • 페이지 테이블에서 프레임이 존재하면 'v(valid)', 없거나 유효하지 않으면 'i(invalid)' 반환

    스레싱

    • 스레싱(thrashing): 동시에 일정 수 이상의 프로그램을 실행했을 때 오히려 CPU 이용률이 떨어지는 상황
      • 가상 메모리를 구현해 다중 프로그래밍(multi programming)을 하면 CPU 이용률이 높아진다.
      • 일정 수 이상으로 다중 프로그래밍 하면 페이지 폴트가 자주 일어난다.
        • 디스크 영역에서 필요한 페이지를 스왑 인하고, 불필요한 페이지를 스왑 아웃하는 작업 빈번하게 발생
          • 다중 프로그래밍 정도가 일정 수준 높아지면 페이징이 빈번히 일어난다.
          • CPU 이용률이 떨어지는 스레싱 발생
      • 스레싱 예방: 워킹 세트(working set) 설정
        • 지역성을 기반으로 자주 사용하는 페이지를 저장한다.
        • 자주 사용하는 페이지를 물리 메모리의 프레임에 고정하면 페이지 폴트가 빈번하게 발생하는 현상을 방지할 수 있다.

    캐시 메모리

    캐시 메모리와 지역성

    • 캐시 메모리(cache memort): CPU와 메인 메모리 간에 데이터 접근 시 속도 차이를 줄이기 위해 사용한다.
      • 지역성(locality) 을 바탕으로 결정한다.
        • CPU가 자주 참조하는 데이터가 고르게 분포되지 않고 특정 부분에 몰려 있는 것
    • 캐시 적중률 높이는 방법
      • 시간 지역성(time locality): 최근 참조한 내용을 다시 참조할 가능성이 높다.
      • 공간 지역성(space locality): 실제 참조한 주소 근처의 내용을 참조할 가능성이 높다.

    캐시 메모리의 매핑 방식

    • 직접 매핑(direct mapping): 메인 메모리를 일정한 크기로 나눠 각 영역을 캐시 메모리에 매핑
      • 메모리 영역(n) : 캐시 메모리(1)
    • 연관 매핑(associative mapping): 규칙 없이 매핑
      • 캐시 메모리에 적재할 때는 간단하지만, 필요한 메모리 영역을 찾을 때 비효율적이다.
    • 집합 연관 매핑(set associative mapping): 직접 매핑 + 연관 매핑 결합

    요약 정리

    1. 메모리 계층 구조

    • 사용 목적에 따라 메모리를 여러 계층으로 둠
    • 레지스터, 캐시 메모리, 주 기억장치(RAM), 보조 기억장치(하드 디스크) 로 구성
    • CPU 접근 속도: 레지스터 > 캐시 메모리 > RAM > 하드디스크

     

    2. 시스템 콜

    • 운영체제의 커널 모드에 접근해 필요한 기능을 수행하기 위해 프로세스에서 호출하는 함수
    • 프로세스 제어, 파일 조작, 장치 조작 등을 수행함

     

    3. 프로세스

    • 실행 중인 하나의 프로그램으로, 하나 이상의 스레드를 가짐
    • PCB(Process Control Block)에 프로세스의 현재 상태, PID(Process ID), 부모 PID 등을 저장함
    • 프로세스마다 독립된 메모리 공간을 가짐
      • 스택: 지역 함수, 함수의 매개변수, 반환 주소 값 저장
      • 힙: 동적 메모리 할당
      • 데이터: 전역 변수, 정적 변수, 배열, 구조체 저장. 세부적으로 초기화된 데이터는 데이터 영역에, 초기화되지 않은 데이터는 BSS 영역에 저장됨
      • 코드: 기계어
    • 프로세스의 상태
      • 생성(new): 프로세스가 PCB를 가지고 있지만 OS로부터 승인(admit) 받기 전
      • 준비(ready): OS로부터 승인받은 후 준비 큐에서 CPU 할당을 기다림
      • 대기(waiting): 프로세스가 입출력이나 이벤트 발생을 기다려야 해서 CPU 사용을 멈추고 기다림
      • 종료(terminated): 프로세스 실행 종료
    • 프로세스의 생성
      • fork() 함수 호출
      • 부모 프로세스는 자식 프로세스의 PID를, 자식 프로세스는 0을 반환함

    4. 스레드

    • 프로세스에서 실제 실행되는 흐름의 단위
    • 각 스레드는 스택 영역을 할당받음
    • 스택을 제외한 영역은 다른 스레드와 공유

    5. 멀티 프로세스와 멀티 스레드

    • 멀티 프로세스
      • 응용 프로그램을 여러 개의 프로세스로 구성하는 것
      • 프로그램을 하나의 프로세스로 구성하는 것보다 안정적임
      • 콘텍스트 스위칭으로 오버헤드가 발생함
      • 독립된 메모리 공간을 갖기 때문에 IPC를 사용함
    • 멀티 스레드
      • 스레드를 여러 개 생성해 작업을 처리하는 것
      • 스택을 지외한 영역은 다른 스레드와 공유하므로 데이터 동기화 필요
      • 콘텍스트 스위칭 시 멀티 프로세스 대비 오버헤드가 적음

    6. 콘텍스트 스위칭

    • 멀티 프로세스 환경에서 CPU가 다른 프로세스를 처리하기 위해 처리 중인 프로세스를 변경하는 것
    • 처리하던 프로세스 정보를 저장하고, 다음으로 처리할 프로세스 정보를 레지스터에 로드하면서 오버헤드 발생

    7. 프로세스 동기화

    • 멀티 프로세스 환경에서 공유 자원의 일관성을 보장하기 위한 방법
    • 상호배제 기법 이용
      • 뮤텍스: 락(lock)을 가진 한 프로세스만 임계 영역에 접근 가능
      • 세마포어: 정해진 개수의 프로세스만 임계 영역에 접근 가능

    8. 교착 상태

    • 상호배제: 하나의 공유 자원을 한 개의 프로세스만 사용할 수 있음
    • 점유와 대기: 프로세스가 최소 하나의 자원을 점유하고 있는 상태에서 추가로 다른 프로세스가 사용 중인 자원을 점유하기 위해 대기함
    • 비선점: 다른 프로세스에 할당된 자원을 뺏을 수 없음
    • 환형 대기: 프로세스가 자신의 자원을 점유하면서 앞이나 뒤에 있는 프로세스의 자원 요구

    9. CPU 스케줄링

    • 목적: 모든 프로세스를 공평하게 실행시키기 위함
    • 스케줄링 알고리즘의 종류
      • FCFS(First Come First Serve): 비선점형, 선입선출
      • SJF(Shortest Job First): 비선점형, 실행 시간이 짧은 것부터 실행
      • RR(Round Robin): 선점형, 타임 슬라이스(또는 타임 퀸텀) 동안만 프로세스 실행 후 교체
      • SRTF(Shortest Remaining Time First): 선점형, 남은 프로세스 중 실행 시간이 가장 짧은 프로세스 실행
    • 스케줄러의 종류
      • 장기 스케줄러: 어떤 프로세스를 준비 큐에 넣을지 결정함
      • 단기 스케줄러: 준비 큐에 있는 프로세스 중 어떤 프로세스를 CPU에 할당할지 결정함
      • 중기 스케줄러: 메모리에 로드된 프로세스 수 관리

    10. 비연속적 메모리 할당

    • 페이징
      • 프로세스의 메모리 영역과 물리 메모리 영역을 일정 크기로 분할하는 방식
      • 프로세스의 메모리 영역을 페이지로, 물리 메모리 영역을 프레임으로 나눔
      • 내부 단편화 문제 발생 가능
    • 세그먼테이션
      • 프로세스를 논리적 단위로 분할하는 방식
      • 데이터를 보호하기 쉬움
      • 스택 세그먼트 영역에서 스택 오버플로 발생 가능

    11. 가상 메모리

    • 메모리 공간의 한계를 극복하기 위해 고안한 방식으로, 프로세스 일부만 메모리에 올림
    • 많은 프로세스를 메모리에 로드할 수 있음
    • 요구 페이징: 필요한 페이지만 메모리에 로드, 페이지 폴트 발생 가능
    • 스레싱: 가상 메모리 환경에서 다중 프로그래밍 정도가 높아지면서 페이지 폴트가 빈번히 발생해 CPU 이용률이 오히려 낮아지는 증상
    728x90
    반응형

    'Book > IT Detail' 카테고리의 다른 글

    운영체제 예상 면접 질문  (2) 2024.09.12

    댓글