읽기 전

  • 불필요한 코드나 잘못 작성된 내용에 대한 지적은 언제나 환영합니다.
  • 개인적으로 사용해보면서 배운 점을 정리한 글입니다.
  • 기술면접만을 준비하기보다 비전공자 입장에서 OS의 기본적인 내용을 짚기 위해 작성되었습니다.

중요도 - 최상: OS가 기술면접에 나온다면 태반은 프로세스/스레드 관련이다.

프로그램의 구조와 동작

  • 프로그램 : 작업을 위해 실행할 수 있는 파일
  • 프로그램 카운터(Program Counter, PC) : CPU가 매 시점마다 메모리의 특정 주소의 명령을 하나씩 읽어와 실행하는 데 이 때 CPU가 수행해야 할 메모리 주소를 담고 있는 레지스터이다. 조건문/반복문/함수 호출로 인한 주소 이동이 없다면 프로그램 카운터는 항상 다음 명령어를 가리켜서 코드를 순차적으로 수행한다.
    • 메모리에는 사용자 프로그램과 운영체제가 같이 적재되어 수행된다. 프로그램 카운터가 운영체제가 위치한 부분을 가리키면 커널 모드에서 명령을 수행 중이고 사용자 프로그램 주소를 가리키면 사용자 모드에서 CPU가 사용자 프로그램을 수행하고 있다고 말할 수 있다.
  • 프로그램의 실행 : 디스크의 실행 파일이 메모리에 적재됨과 프로그램이 CPU를 할당받고 명령을 수행하고 있는 상태를 의미한다.

프로세스와 스레드

  • 프로세스 : 운영체제로부터 시스템을 할당받는 작업의 단위, 동적인 개념으로 현재 실행 중인 프로그램이다.
    • 기본적으로 최소 1개의 스레드(메인 스레드)를 갖는다.

프로세스 구조

  • 프로세스의 주소 공간 / 가상 메모리 / 논리적 메모리 : 실제 메모리 주소와 독립적으로 각 프로그램마다 독자적인 주소 공간을 갖기에 가상 메모리, 논리적 메모리라고도 부르며 코드(code), 데이터(data), 스택(stack), 힙(heap) 등으로 구성된다.
    • 코드 영역 : 사용자가 작성한 프로그램 함수들의 코드가 CPU에서 수행할 수 있는 기계어 명령 형태로 변환되어 저장되는 부분
    • 데이터 영역 : 전역 변수 등 프로그램이 사용하는 데이터를 저장하는 부분
    • 스택 영역 : 함수가 호출될 때 호출된 함수의 수행을 마치고 복귀할 주소 및 데이터를 임시로 저장하는 공간이다.
    • 운영체제 역시 프로그램이므로 운영체제 커널도 프로세스 주소 공간을 갖는다.
      • 커널의 코드 영역 : CPU와 메모리 관리, 인터페이스 제공 코드 등이 주를 이룬다.
      • 커널의 데이터 영역 : 자원을 관리하기 위한 자료구조를 저장한다.
      • 커널의 스택 영역 : 함수 호출 시 복귀 주소를 저장하기 위한 용도는 맞지만 사용자 프로그램이 시스템 콜을 하여 커널 함수로 접근 시 상황을 고려하여 일관성 유지를 위해 프로세스마다 별도의 스택을 둔다.
        • 일반 프로그램이 시스템 콜을 할 때 CPU의 수행 주체가 프로그램에서 OS로 전환되며 PCB에 일반 프로그램 복귀 정보를 저장한다.
        • 커널 스택에 일반 프로그램에 대한 별도의 스택을 두어 관리한다.
  • 힙 영역 : 동적으로 할당되는 데이터들을 위해 존재하는 공간 (new(), mallock() 등)
  • PCB : OS가 프로세스를 표현하는 개체. 문맥교환 시 PCB와 TCB를 모두 저장한다.
  • 프로세스의 두 가지 실행 상태
    • 사용자 모드에서의 실행 상태(user mode running) : 자신의 주소 공간에 정의된 코드를 실행
    • 커널 모드에서의 실행 상태(kernel mode running) : 시스템 콜 함수를 실행
      • 시스템 콜을 하여 실행되는 코드가 커널의 코드라 할 지라도 커널은 호출 프로세스의 일을 대행할 뿐이므로 요청 프로세스 A가 여전히 실행 상태에 있다고 간주하며 단지 코드 실행 주체를 구분짓기 위해 두 가지로 나눈 것이다.

스레드 구조

  • 스레드 : 프로세스가 할당받은 자원을 이용하는 실행 흐름의 단위. 프로세스의 특정한 수행 경로이다.

Technical_Interview_Operation_System_002_001

  • 프로세스 주소공간 내에서 각각 stack만 따로 할당 받으며 별도의 PC 레지스터를 갖는다.
  • 프로세스의 주소공간(코드, 데이터)이나 자원(힙 영역)을 같은 프로세스의 스레드끼리 공유하며 힙 메모리에 서로 읽고 쓰기 작업을 수행한다.
  • 한 스레드가 프로세스 자원 변경 시 다른 스레드도 그 변경 결과를 즉시 확인 가능하다.
  • TCB : PC 레지스터, CPU 정보, PCB 포인터를 갖는다. 스레드끼리의 문맥 교환 시 TCB만 저장한다.
  • Java에서의 스레드 : 일반 스레드와 차이는 거의 없고 JVM이 OS의 역할을 수행한다.
    • Java에선 프로세스가 존재하지 않고 스레드만 존재하며 스레드의 스케쥴링은 JVM이 책임진다.
    • OS에서의 프로세스가 Java에서는 스레드처럼 간주되어 OS가 관리하던 프로세스 수, 메모리 위치, 프로세스의 상태, 우선 순위 등이 전부 스레드로 바뀌어 JVM이 관리한다.
    • 개발자는 스레드로 동작할 코드를 작성해 JVM이 스레드를 실행하도록 요청

멀티 프로세스, 멀티 스레드 등 다중처리

  • 멀티 프로세스 : 하나의 프로그램을 여러 프로그램으로 구성하여 각 프로세스가 하나의 작업 처리(병렬 처리)
    • 장점 : 자식 프로세스 중 하나에 문제가 발생해도 다른 프로세스에는 영향이 없어 안정성이 높다.
    • 단점
      • 문맥 교환에서의 오버헤드 : 캐시 메모리 리셋 등 무거운 작업 발생
      • 프로세스 간 복잡하고 어려운 IPC : 독자적인 메모리 공간으로 변수 공유가 안됨
  • 멀티 스레드 : 하나의 프로세스에 여러 스레드로 자원을 공유하며 작업을 나누어 수행
    • 장점
      • 일부 스레드가 중단되거나 긴 작업을 수행해도 프로그램 동작이 계속되어 사용자와의 응답성 증가
      • 시스템 자원의 효율성 증가 : 단일 스레드와 비교할 때 프로세스 생성 시 자원을 할당하는 시스템 콜 감소
      • 처리 비용 감소 : 코드, 데이터, 힙을 공유하기에 다른 스레드들 간의 공유가 쉽다.
      • 문맥 교환 비용 감소 : 캐시 메모리를 비울 필요가 없어 비교적 가벼운 TCB만 전환하면 된다.
    • 단점
      • 자원을 공유함에 따라 동기화 문제 발생 가능(병목 현상, 데드락)
      • 과도한 동기화 과정으로 인해 성능 저하 가능성이 있음
      • 하나의 스레드의 문제로 예외상황 등 발생 시 전체 프로세스에 영향을 주거나 아예 종료될 수 있다.
      • 단일 프로세스 환경에서는 효과가 저하되어 스레드 생성시간으로 인해 단일 스레드보다 느리다.
  • 멀티 코어 : CPU 내부에 레지스터와 캐시를 갖는 코어만 따로 회로를 구성
  • 멀티 프로그래밍 - 멀티 태스킹
    • 멀티 프로그래밍 : 하나의 메모리에 동시에 여러 프로세스를 적재
    • 멀티 태스킹 : 멀티 프로그래밍된 메모리에 대해 CPU가 시분할로 여러 프로세스를 concurrency하게 처리함(concurrency : 동시에 처리되는 것처럼 보임)

프로세스 관리

  • 프로세스의 문맥(context) : 프로세스가 어떤 상태에서 수행되고 있는지 규명하기 위해 필요한 정보
    • 하드웨어 문맥 : CPU의 수행 상태를 기록. 프로그램 카운터 값, 레지스터에 저장된 값
    • 프로세스의 주소 공간 : 코드/데이터/스택으로 구성된 독자적인 주소 공간
    • 커널 상의 문맥 : 프로세스를 관리하기 위한 자료구조를 취급. PCB, 커널 스택 등이 있음
  • 프로세스의 상태 : 기본적으로 실행, 준비, 봉쇄 세가지로 구분되나 시작, 완료, 정지도 있음
    • 실행(running) 상태 : 프로세스가 CPU를 할당받아 기계어 명령을 수행 중인 상태
    • 준비(ready) 상태 : CPU만 할당받으면 명령 수행이 가능하지만 아직 못 받은 상태
    • 봉쇄(blocked) 상태 : CPU를 할당받아도 당장 명령을 실행할 수 없는 상태
    • ex) 프로세스가 요청한 입출력 작업을 진행하고 있는 경우
    • 시작(new) 상태 : 프로세스가 생성되어 프로세스를 위한 자료구조는 있으나 메모리 획득 권한을 아직 받지 못한 상태
    • 완료(terminated) 상태 : 프로세스는 종료되었으나 OS가 프로세스와 관련된 자료구조를 아직 정리하지 못한 상태
    • 중지(suspend) 상태 : 중기 스케쥴러의 등장으로 새로 도입된 개념. 메모리 공간을 위해 메모리를 빼앗겨 디스크의 스왑 영역으로 옮겨진 상태 - 아래에서 다시 다룸

Technical_Interview_Operation_System_002_002.png

  • 문맥 교환(context switch) : 기존 수행 중인 사용자 프로세스의 문맥을 저장하고 새로운 사용자 프로세스의 문맥을 세팅하여 CPU 제어권을 넘기는 과정
    • 프로세스가 교체될 경우 PCB와 TCB를 교환하지만 멀티 스레드 환경에서 스레드의 문맥교환은 TCB만 교환되어 오버헤드가 비교적 적다. (문맥 교환의 기본 단위는 TCB)
    • 기존 할당 프로세스 : 프로세스의 문맥을 PCB에 저장
    • 신규 할당 프로세스 : 프로세스의 문맥을 PCB로부터 실제 하드웨어로 복원
    • 시스템 콜이나 인터럽트 처리로 인해 CPU의 제어권을 OS로 넘기는 행위는 문맥 교환으로 간주하지 않는다. 프로세스의 실행 모드가 바뀔 뿐 시스템 콜/인터럽트 처리가 끝나면 마저 기존 프로세스로 복귀하여 수행하기 때문이다.
  • CPU 디스패치(dispatch) : 준비 상태의 프로세스 중 CPU를 할당받은 프로세스를 선택해 제어권을 넘기는 과정
  • ex) 타이머 인터럽트나 실행 중인 프로세스의 입출력 요청으로 인한 봉쇄 상태 전환 시 발생

프로세서 제어 블록 - PCB, 스레드 제어 블록 - TCB

  • PCB에 저장되는 정보
    • 프로그램 카운터의 값 : 다음에 실행할 명령어의 주소- 단일 스레드, 멀티 프로세스 환경
    • CPU 레지스터의 값 : CPU 연산을 위해 현재 레지스터의 저장 값을 나타냄- 단일 스레드, 멀티 프로세스 환경
    • 프로세스의 상태 : CPU 할당 여부 결정에 필요 - new, ready, waiting 등의 상태 저장
    • CPU 스케쥴링 정보 : 프로세스의 우선순위, 스케쥴 큐에 대한 포인터 등을 저장
    • 메모리 관리 정보 : 페이지 테이블, 세그먼트 테이블 등의 메모리 할당 관련 저장
    • 입출력 상태 정보 : 프로세스에 할당된 입출력 장치와 열었던 파일 정보 저장
    • 자원 사용 정보 : 사용된 CPU 시간, 시간 제한, 계정 번호 등 저장
  • TCB에 저장되는 정보
    • 프로그램 카운터 값 : 다음에 실행할 명령어의 주소 - 멀티 스레드 환경
    • CPU 레지스터의 값 : CPU 연산을 위해 현재 레지스터의 저장 값을 나타냄 - 멀티 스레드 환경

프로세스의 스케쥴링

큐는 각 프로세스의 PCB를 연결리스트로 관리한다.

  • 준비 큐 : CPU를 할당받기 위해 다기 중인 준비 상태의 프로세스들을 담는다.
  • 장치 큐 : 장치 별로 특정 자원을 기다리는 프로세스들을 담은 큐. 동기성을 보장하며 장치 큐에 속한 프로세스는 봉쇄 상태이다.
  • 작업 큐 : 준비 큐, 장치 큐의 모든 프로세스는 작업 큐에 속한다. 모든 프로세스를 관리.
  • 스케쥴러 : 어떤 프로세스에게 자원을 할당할 지 결정하는 OS 커널의 코드
    • 장기 스케쥴러(Long-term scheduler, job scheduler)
      • 메모리와 디스크 사이의 스케쥴링 담당
      • 프로세스에 메모리 및 각종 리소스 할당(admit)
      • degree of Multiprogramming(실행 중인 프로세스의 수) 제어
      • 메모리에 너무 많은 프로세스가 적재되면 CPU 수행에 필요한 데이터를 적재하지 못해 디스크로 빈번하게 요청하여 인터럽트가 수시로 발생
      • 프로세스의 상태를 new에서 ready로 전환하며 현대 시분할 시스템에서는 메모리가 충분해 잘 쓰이진 않는다.
    • 어떤 프로세스를 준비 큐에 넣을 지 결정하여 프로세스의 상태를 시작에서 준비로 바꾼다. 프로세스가 CPU에서 실행되기 위해선 메모리를 가져야하기 때문이다.
    • 단기 스케쥴러(Short-term scheduler, CPU scheduler)
      • CPU와 메모리 사이의 스케쥴링 담당
      • 준비 큐에 있는 프로세스 중 실행으로 바꿀 프로세스 결정
      • 프로세스에 CPU 할당
      • 시분할 시스템의 타이머 인터럽트 발생 시 단기 스케쥴러가 호출된다.
    • 중기 스케쥴러(Medium-term scheduler, Swapper)
      • 메모리 공간 확보를 위해 프로세스를 메모리에서 디스크로 보내버림(swapping)
      • 프로세스에 할당된 메모리를 deallocate
      • degree of Multiprogramming 제어
      • 프로세스의 상태를 준비에서 정지(suspend)로 전환
    • 메모리 자원이 충분해져 장기 스케쥴러의 효용이 떨어지자 등장한 개념
    • 스왑 아웃(swap out) : 중기 스케쥴러에 의해 메모리에 적재된 프로세스의 메모리를 빼앗고 그 내용을 디스크 스왑 영역에 저장하는 행위
    • 중지 상태 : 중기 스케쥴러에 의해 프로세스가 스왑 아웃된 상태
      • 중지준비 : 준비 상태의 프로세스가 스왑 아웃
      • 중지봉쇄 : 봉쇄 상태의 프로세스가 스왑 아웃, 봉쇄가 끝나면 중지준비로 변경

Technical_Interview_Operation_System_002_003.png

프로세스의 생성

최초의 프로세스는 OS가 생성하고 이후는 각 프로세스가 다른 프로세스를 생성한다.

  • 부모/자식 프로세스 : 프로세스를 생성한 프로세스 / 프로세스로부터 생성된 프로세스
    • 프로세스의 생성 이후 : 부모는 자식의 수행이 완료될 때까지 봉쇄되거나 같이 수행되며 CPU 점유율 경쟁
    • 프로세스의 종료 : 모든 자식 프로세스가 종료된 뒤에야 부모 프로세스가 종료됨
    • 자식 프로세스 주소 공간 : 부모 프로세스의 주소 공간의 내용을 그대로 복제한 뒤 덮어씌우며 프로그램 수행
    • 로그아웃 이후 자식 프로세스 유지 : 로그인 하단에서 생성한 자식 프로세스를 로그아웃 이후에도 유지하고 싶을 경우 로그아웃 후에도 유지되는 부모 프로세스에게 이양 후 로그인 하단의 프로세스를 종료한다.
    • 생성된 자식 프로세스의 실행 : 부모 프로세스의 주소공간을 복제함에 따라 부모가 수행한 지점(프로그램 카운터 지점)에서 시작된다. 다만, 부모에게 프로세스 복제 결과값을 1로, 자식에겐 0을 주어 자신이 복제본임을 구분하게 한다. 이후 부모의 복제된 내용과 다른 프로그램을 수행하기 위해 별도의 실행 함수를 호출하여 주소 공간을 덮어 씌운다.
    • 부모와 자식의 동기화 : 실행 후 서로 경쟁하지 않고 자식의 결과를 받아서 사용해야 하면 부모는 wait() 호출하여 봉쇄상태에 두고 자식 종료 후에 부모를 준비 큐에 넣는다.

프로세스 간 통신

  • IPC(Inter-Process Communication) : 실행 중인 다른 프로세스 간 발생하는 통신이며 의사소통 기능과 동기화를 보장하기 위한 매커니즘이다.
    • 메세지 전달 : 프로세스 간 공유 데이터 없이 메세지를 주고받아 통신
      • send&receive : OS의 시스템 콜 함수
      • 직접 통신 : 두 프로세스 간 직접 통신한다. 통신하려는 프로세스를 명시적으로 표시하며 두 프로세스 간에는 오직 1개의 커뮤니케이션 링크만 존재한다.
        • 익명 파이프 : 단방향 파이프로 한 쪽은 전송만, 한쪽은 수신만 가능
          • 장점 : 사용이 매우 간단하므로 단순 데이터 흐름에서는 효율적임
          • 단점 : 양방향 통신에서는 파이프 2개가 필요하므로 구현이 어려움
        • 기명(named) 파이프 : 익명 파이프와 같이 반이중 통신 파이프로 이름이 있는 파일을 사용한다.
          • 장단점은 익명 파이프와 동일
      • 간접 통신 : 메일 박스나 포트로부터 메세지를 송/수신한다. 각 메일 박스의 고유한 ID를 공유하는 프로세스들끼리만 메세지를 전달한다. 송신자가 메일 박스로 메시지 전달 후 메일 박스가 수신자에게 메세지(공유하고자 하는 데이터의 메모리 주소) 송신, 수신자 특정은 링크(메일박스) 할당 등의 방법으로 해결한다.
        • 메시지 큐 : 메일박스(1개만 전송)의 배열 형태로 구성, 데이터의 흐름이 아닌 메모리 공간이다.
    • 공유 메모리 : 프로세스들이 주소 공간의 일부를 공유한다. 원칙적으로 개별 공간이지만 시스템 콜로 공유를 지원한다. 물리적 메모리에 매핑 시 공유 메모리 주소 영역은 A, B 프로세스가 서로 같은 주소에 매핑된다.
      • 동기화 문제 : 커널이 책임지지 않으므로 프로세스들끼리 직접 해결해야 한다.

Technical_Interview_Operation_System_002_004.png

관련 포스팅

1. 기술면접을 위한 OS 개념정리 01 - CPU 스케쥴링, 입출력 관리, 디스크 관리

2. 기술면접을 위한 OS 개념정리 03 - 메모리, 가상 메모리 관리, 웹캐싱 기법

3. 기술면접을 위한 OS 개념정리 04 - 프로세스 동기화, 데드락

+ Recent posts