📌 운영체제

  • 실행할 프로그램에 필요한 자원을 할당하고
  • 프로그램이 올바르게 실행되도록 돕는 프로그램
  • 동시다발적으로 생성, 실행, 삭제되는 다양한 프로세스를 관리한다.
    • 프로세스, 스레드, 프로세스 동기화, 교착 상태 해결
  • 자원 접근 및 할당
    • CPU(CPU 스케줄링), 메모리(페이징, 스와핑), 입출력장치

메모리 구조

  • 커널 영역(Kernel)
    • 운영체제의 핵심 영역
    • 커널 : 운영체제의 핵심 서비스를 담당하는 부분
    • 응용 프로그램이 자원에 접근하려면 운영체제에 도움을 요청(운영체제의 코드를 실행)해야 한다. -> 이중 모드로 구현
    • 시스템의 모든 것을 통제하기 때문에 사용자(유저 모드)가 직접 접근이 불가능하다.
    • 접근 시 system call(시스템 콜)을 통한 커널 모드 전환이 필요하다.
  • 유저 영역
    • 스택 영역, 힙 영역, 데이터 영역, 코드 영역
    • 코드 영역
      • 실행할 수 있는 코드, 기계어로 이루어진 명령어 저장
      • read-only, 데이터가 아닌 CPU가 실행할 명령어가 담기기에 쓰기 금지
    • 데이터 영역
      • 전역 변수와 정적 변수가 저장되는 영역
    • 힙 영역
      • 동적할당된 변수가 저장되는 영역, 프로그래머가 직접 할당 가능
      • 동적할당 : 프로그램이 실행되는 도중에 메모리를 할당하는 것. 동적할당에서 포인터가 저장되는 곳은 스택 영역이다. 메모리 사용 후, 동적할당 해제를 하지 않으면 메모리 누수(memory leak)가 발생할 수 있다.
    • 스택 영역
      • 함수 내에서 지역변수와 매개변수가 저장되는 영역
      • 스택 영역이 생성될 때(함수 실행) 필요한 크기만큼 만들어지고, 데이터 저장
      • 함수가 끝나면 스택 영역 소멸

이중 모드

  • CPU가 명령어를 실행하는 모드를 크게 사용자 모드, 커널 모드로 구분하는 방식
  • 사용자 모드
    • 운영체제 서비스를 제공받을 수 없는 실행 모드
    • 커널 영역의 코드를 실행할 수 없는 실행 모드
    • 자원 접근 불가능
  • 커널 모드
    • 운영체제의 서비스를 제공받을 수 있는 실행 모드
    • 자원 접근을 비롯한 모든 명령어 실행 가능
  • 시스템 호출(시스템 콜, system call)
    • 커널 모드로 전환하여 실행하기 위해 호출
    • 운영체제 서비스를 제공받기 위해 커널 모드로 전환하는 방법
    • 종류
      • 프로세스 관리 : fork(), exit(), waitpid()
      • 파일 관리 : open(), close(), read(), write()
      • 디렉터리 관리 : mkdir(), rmdir()
      • 파일 시스템 관리 : mount(), umount()

프로세스

  • 운영체제로부터 시스템 자원을 할당받는 작업의 단위
  • 메모리에 올라와 실행되고 있는 프로그램의 인스턴스
  • 동적인 개념으로 실행된 프로그램을 의미한다.
  • 프로세스 확인 방법
    • 윈도우 : 작업 관리자
    • 리눅스, macOS : ps 명령어
  • 포그라운드 프로세스(Foreground process)
    • 사용자가 볼 수 있는 공간에서 실행되는 프로세스
  • 백그라운드 프로세스(background process)
    • 사용자와 직접 상호작용이 가능한 프로세스
    • 사용자와 상호작용하지 않고 정해진 일만 수행하는 프로세스 -> 데몬(daemon), 서비스(service)

프로세스 제어 블록(PCB)

  • 모든 프로세스는 실행을 위해 CPU가 필요하다.
  • 하지만 CPU 자원은 한정되어 있기 떄문에, 프로세스들은 돌아가면서 한정된 시간만큼 CPU를 사용해야한다.
  • 프로세스를 관리하기 위해서 PCB 사용
  • 프로세스 관련 정보를 저장하는 자료구조
  • 대표적인 정보
    • 프로세스 ID(PID)
      • 특정 프로세스를 식별하기 위해 부여하는 고유 번호(ex. 학번, 사번)
    • 레지스터 값
      • 프로세스가 자신의 실행 차례가 오면, 이전에 사용한 레지스터 중간 값을 모두 복원한다.
      • 프로그램 카운터, 스택 포인터, ..
    • 프로세스 상태
      • 생성(create), 준비(ready), 실행(running), 대기(waiting), 완료(terminated)
    • CPU 스케줄링 정보
      • 우선 순위, 최종 실행 시각, CPU 점유 시간
      • 프로세스가 언제, 어떤 순서로 CPU를 할당 받을지에 대한 정보
    • 메모리 정보
      • 프로세스가 어느 주소에 저장되어 있는지에 대한 정보
      • 페이지 테이블 정보
    • 사용한 파일과 입출력장치 정보

문맥 교환(context switch)

  • A 프로세스에서 B 프로세스로 넘어 갈 때, 어떤 작업이 수행?
    • 기존 실행 프로세스가 지금까지의 중간 정보를 백업한다.
    • 중간 정보 : context(문맥)
    • 다음 차례가 왔을 때 실행을 재개하기 위해 저장하는 정보
  • 기존 실행 프로세스 문맥을 백업하고, 새로운 프로세스 실행을 위해 문맥을 복구하는 과정

프로세스 상태

  • 생성 상태(create)
    • 이제 막 메모리에 적재되어 PCB를 할당 받은 상태
    • 준비가 완료되면 준비 생태로
  • 준비 상태(ready)
    • 바로 실행 가능하지만, 순서를 기다리는 상태
  • 실행 상태(running)
    • CPU를 할당 받아 실행 중인 상태
    • 할당 시간을 모두 사용하면,(타이머 인터럽트 발생) 준비 상태로 이동
    • 실행 도중 입출력장치를 사용하면 입출력 작업이 끝날 때까지 대기 상태로
  • 대기 상태(waiting)
    • 프로세스가 실행 도중 입출력장치를 사용하는 경우
    • 입출력 작업이 끝나면 준비 상태로 이동
  • 종료 상태(terminated)
    • 프로세스가 종료된 상태
    • PCB 정리


스레드

  • 프로세스를 구성하는 실행 흐름의 단위
  • 하나의 프로세스는 하나 이상의 스레드를 가질 수 있다.
  • 단일 스레드 프로세스 : 실행 흐름 1개
  • 멀티 스레드 프로세스 : 실행 흐름 2개 이상, 여러 명령어 동시 실행 가능
  • 스레드의 구성 요소
    • 스레드 ID, 레지스터 값, 스택 등등
    • 실행에 필요한 최소한의 정보를 갖고 있다.
    • 같은 프로세스에 있는 스레드 끼리 자원을 공유할 수 있다.


 

프로세스 VS 스레드

- 프로세스는 메모리에 올라가는 프로그램으로 운영체제로부터 메모리, 주소 공간 등을 할당 받는다.

- 멀티 프로세스 환경에서는 메모리에 올라간 다양한 프로세스들이 CPU를 선점하며 진행된다.

- CPU 선점과정을 통해 PCB에 각각의 프로세스들이 실행되었던 정보들은 문맥 교환을 통해 저장된다.

- 스레드는 각 프로세스에서 실행 단위를 뜻한다. 하나의 프로세스에 여러 개의 스레드가 동작하는 것을 멀티 스레드라고 한다.

- 각각 스레드는 한 프로세스에서 힙 영역과 데이터 영역을 공유하고, 각 스레드마다 스택과 PC레지스터 값이 따로 존재한다.

- 멀티 스레드는 생성과 관리의 중복을 최소화하고, 멀티 프로세스에 비해 문맥 교환 비용이 낮다.

 

 

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

  • 멀티 프로세스의 프로세스는 자원을 서로 공유하지 않는다.
    • 프로세스 간 통신(IPC)으로, 프로세스 간에도 자원을 주고받을 수 있다.
  • 멀티 스레드에서는 하나의 프로세스 자원을 스레드가 서로 공유한다.

 

멀티 스레드

- 장점 : 여러 프로세스를 동시에 처리하던 일을 자원과 메모리 공유로 자원 소모에 대한 비용 절감

- 또한 프로세스의 문맥 교환과 다르게 캐시 메모리를 비울 필요가 없어 속도가 빠르다.

- 단점 : 여러 자원을 공유하기 때문에, 동기화 문제를 해결하기 위한 작업 필요

 

-> 멀티 프로세스도 다른 프로세스가 점유하고 있는 자원에 대해 접근할 때 동기화 문제가 발생할 수 있다.

- 문재 해결 : 임계 영역으로 동시 접근 방지 -> 세마포어, 뮤텍스

 


CPU 스케줄링

  • 운영체제가 프로세스들에게 공정하고 합리적으로 CPU 자원을 분배하는 것
  • 프로세스 우선순위(priority) 에 따라 프로세스 실행 순서가 정해진다.
  • 스케줄링 큐

선점(preemptive) 스케줄링

  • 프로세스가 CPU를 할당받아 실행 중이어도, 운영체제가 CPU의 사용권을 선점 가능
  • 처리 시간 예측이 어렵다.
  • 잦은 문맥 교환으로 오버헤드 발생 가능성이 있다.
  • CPU 사용 독점 문제를 막을 수 있다.
  • Interrupt, I/O or Event Completion, I/O or Event Wait, Exit

비선점(non-preemptive) 스케줄링

  • 프로세스가 CPU를 점유하고 있으면, 사용을 뺐을 수 없는 방식
  • 필요한 문맥 교환만 일어나기 때문에 오버헤드가 상대적으로 적다.
  • 처리 시간 예측이 쉽다.
  • I/O or Event wait, Exit

프로세스 상태 다이어그램

  • 승인(Admitted) : 프로세스 생성이 가능하여 승인된 상태
  • 스케줄러 디스패치(Scheduler dispatch) : 준비 상태에 있는 프로세스 중 하나를 선택하여 실행
  • 인터럽트(Interrupt) : 예외, 입출력, 이벤트 등이 발생해서 현재 실행 중인 프로세스를 준비 상태로 바꾸고, 해당 작업을 먼저 처리
  • 입출력 또는 이벤트 대기(I/O or event wait) : 실행 중인 프로세스가 입출력이나 이벤트를 처리해야 하는 경우, 입출력/이벤트가 모두 끝날 때 까지 대기 상태로 만드는 것
  • 입출력 또는 이벤트 완료(I/O or event completion) : 입출력/이벤트가 끝난 프로세스를 준비 상태로 전환하여 스케줄러에 의해 선택될 수 있도록 만드는 것

CPU 스케줄링 종류

  • 비선점 스케줄링
    1. FCFS(First Come First Served) 선입 선처리 스케줄링
      • 준비 큐에 삽입된 순서대로 처리하는 비선점 스케줄링
      • 먼저 CPU를 요청한 프로세스부터 CPU 할당
      • 실행 시간이 짧은 것이 뒤로 가면 평균 대기 시간이 길어진다.
    2. SJF(Shortest Job First) 최단 작업 우선 스케줄링
      • 수행 시간이 가장 짧다고 판단되는 작업을 먼저 수행
      • FCFS 보다 평균 대기 시간 감소, 짧은 작업에 유리하다.
  • 선점 스케줄링
    1. RR(Round Roubin) 라운드 로빈
      • FCFS + 타임 슬라이스(time slice) or Time Quantum
      • 타임 슬라이스 : 실행의 최소 단위 시간, 각 프로세스가 CPU를 사용할 수 있는 정해진 시간
      • 정해진 시간을 모두 사용해도, 프로세스가 완료되지 않으면 큐의 맨 뒤에 삽입(문맥 교환)
      • Time Quantum이 크면 FCFS와 같고, 작으면 문맥 교환이 잦아져서 오버헤드 발생
    2. SRT(Shortest Remaining Time) 최소 잔여 시간 우선 스케줄링
      • SJF + RR
      • 정해진 시간만큼 CPU를 사용하고, 다음으로 CPU를 사용할 프로세스를 남은 작업 시간이 가장 적은 프로세스를 선택한다.
    3. Priority Scheduling(우선순위 스케줄링)
      • 프로세스들에 우선순위를 부여하고, 우선순위 높은 프로세스부터 실행
      • 우선순위가 같은 프로세스들은 FCFS 스케줄링
      • 단점 : 우선 순위가 낮은 프로세스를 무한정 기다리는 기아(starvation) 현상
      • Aging 방법으로 기아 현상 해결이 가능하다.
      • Aging : 오랫동안 대시한 프로세스의 우선순위를 점차 높이는 방식
    4. Multilevel-Queue(다단계 큐)
      • 우선순위 스케줄링이 발전된 형태
      • 우선순위별로 준비 큐를 여러 개 사용하는 스케줄링 방식
      • 우선순위가 가장 높은 큐에 있는 프로세스를 먼저 처리하고, 가장 높은 큐가 비어 있으면 그 다음 우선순위 큐에 있는 프로세스를 처리한다.
      • 우선순위가 높은 큐는 작은 Time Quantum, 우선순위가 낮은 큐는 큰 Time Quantum
    5. Multilevel feedback queue(다단계 피드백 큐 스케줄링)
      • 큐 간의 이동이 가능한 다단계 큐 스케줄링
      • 자연스럽게 CPU 집중 프로세스의 우선순위는 상대적으로 낮아지고, 입출력 집중 프로세스의 우선순위는 높아진다.

동기화

  • 프로세스들의 수행 시기를 맞추는 것
  • 실행 순서 제어 : 프로세스를 올바른 순서대로 실행, reader writer problem
    • reader와 writer 프로세스는 아무렇게나 실행 되면 X
  • 상호 배제 : 동시 접근이 안되는 자원에 하나의 프로세스만 접근하게 하기, bank account problem
    • 한 번에 하나의 프로세스만 접근해야 하는 자원에 동시 접근을 피하기 위한 동기화
    • ex. 계좌에 입금할 때 현재 잔액 + 추가 금액
  • 공유 자원 : 여러 프로세스 혹은 스레드가 공유하는 자원
    • ex. 전역 변수, 파일, 입출력장치, 보조기억 장치 등등
  • 임계 구역 : 동시에 실행하면 문제가 발생하는 자원에 접근하는 코드 영역
    • ex. 총합 변수, 잔액 변수
  • 레이스 컨디션(race condition) : 임계 구역에 동시에 접근하면 자원의 일관성이 꺠지는 것

Race Condition

  • 공유 자원에 대해 여러 프로세스가 동시에 접근할 때, 결과값에 영향을 줄 수 있는 상태

동기화 기법

  • 뮤텍스 락, 세마포어, 모니터
  • 뮤텍스 락
    • 상호 배제를 위한 동기화 도구, key를 기반으로 상호 배제
    • 전역 변수 1개, 함수 2개로 구현
    • 자물쇠 역할 : 프로세스들이 공유하는 전역 변수 lock
    • 임계 구역을 잠그는 역할 : acquire 함수
    • 임계 구역의 잠금을 해제하는 역할 : release 함수
    • busy waiting(바쁜 대기) 적용 : 임계 구역이 잠겨 있는지 확인하는 작업을 무한으로 작동
  • 세마포어
    • 일반화된 방식의 동기화 도구
    • 공유 자원이 여러 개 있는 경우에도 적용 가능
    • 멀티프로그래밍 환경에서 공유 자원에 대한 접근을 제한하는 방법
    • 전역 변수 1개, 함수 2개로 구현
    • 전역 변수 S : 임계 구역에 진입할 수 있는 프로세스 개수를 나타내는 변수
    • wait 함수 : 임계구역에 들어가도 되는지, 기다려야 하는지 알려주는 함수
    • signal 함수 : 임계 구역 앞에서 기다리는 프로세스에 가도 된다는 신호를 주는 함수
    • busy waiting(바쁜 대기) 적용 : CPU 사이클 낭비의 단점
      • 계속 반복되는 연산으로 CPU 낭비
      • 해결 방법
        • 사용할 수 있는 자원이 없을 경우 대기 상태로 만든다. -> 해당 프로세스의 PCB를 대기 큐에 삽입
        • 사용할 수 있는 자원이 생겼을 경우 대기 큐의 프로세스를 준비 상태로 만든다. -> 해당 프로세스의 PCB를 대기 큐에서 꺼내 준비 큐에 삽입
wait() {
    while (S <= 0) // 임계 구역에 진입할 수 있는 프로세스 개수가 0 이하면
        ; // 사용 가능한 자원이 있는지 확인하고
    S--; // 임계 구역에 진입할 수 있는 프로세스 개수가 1개 이상이면 S 감소하고 임계 구역 진입
}

signal() {
    S++; // 임계 구역에서의 작업을 마치고 S 증가
        }

 


교착 상태(Dead lock)

  • 두 개 이상의 프로세스나 스레드가 서로 자원을 얻지 못해서 다음 처리를 하지 못하는 상태
  • 무한히 다음 자원을 기다리는 상태
  • 교착 상태 조건
    • 상호 배제 : 한 프로세스가 사용하는 자원을 다른 프로세스가 사용할 수 없는 상태
    • 점유와 대기 : 자원을 할당 받은 상태에서 다른 자원을 할당 받기를 기다리는 상태
    • 비선점 : 어떤 프로세스도 다른 프로세스의 자원을 강제로 빼앗지 못하는 상태
    • 원형 대기 : 프로세스들이 원의 형태로 자원을 대기하는 상태
  • 교착 상태 해결 방법
    • 예방(prevention) : 교착 상태가 발생하지 않도록 발생 조건 중 하나를 없애기
    • 회피(avoidance) : 예방보다 덜 엄격한 제약 조건으로 자원을 좀 더 효율적으로 사용할 수 있도록 해결
      • 은행원 알고리즘 : 프로세스가 자원을 요구할 때, 시스템은 자원을 할당한 후에도 안정 상태인지 사전에 검사하여 교착 상태 회피
    • 회복 : 교착 상태 발생을 인정하고 사후에 조치하는 방식
      • 선점을 통한 회복, 프로세스 강제 종료를 통한 회복
    • 무시 : 교착 상태를 해결할 때, 문맥 교환에 의한 오버헤드로 성능저하가 일어날 수 있어서 무시하는 방법

 

 

메모리 단편화

- 단편화(fragmentation) : 프로세스들이 메모리에 적재되고 해제되는 것이 반복되면, 프로세스들 사이에 사용 못하는 공간이 생긴다.

- 외부 단편화 : 메모리 공간 중 사용하지 못하게 되는 일부 물리 메모리 사이에 남는 공간들을 합쳤을 때 다른 프로세스를 할당할 수 있는 문제

- 내부 단편화 : 프로세스가 사용하는 메모리 공간 내에 사용하지 않는 부분

 

 

페이징

- 페이징 기법으로 논리 메모리는 물리 메모리에 저장될 때 연속되어 저장될 필요 없이 물리 메모리의 남는 프레임에 적절히 배치

- 페이지와 프레임을 대응하는 페이징 테이블 필요(paging table)

- 장점 : 외부 단편화를 해결

- 단점 : 내부 단편화 비중이 늘어난다.

 

 

세그멘테이션

- 페이징처럼 논리, 물리 메모리를 같은 크기의 블록이 아닌 서로 다른 크기의 논리적 단위인 세그먼트로 분할해서 할당

- 각 세그먼트는 연속적인 공간에 저장된다.

- mapping을 위한 segment table 필요

- 필요한 메모리 공간만큼 메모리를 할당하기 때문에 내부 단편화 문제는 없지만, 중간에 메모리를 해제하면 외부 단편화 발생

 

+ Recent posts