운영체제

운영체제

  • 운영체제는 컴퓨팅 사고가 고도로 발달한 분들이 모여서 만든 소프트웨어이다
  • 운영체제는 컴퓨터 하드웨어/소프트웨어의 전반적인 동작을 이해하는데 도움이 된다

운영체제 역할

  • 시스템 자원 관리자
    • 컴퓨터 하드웨어는 스스로 할 수 있는 것이 없다
      • 프로그램당 CPU 사용여부를 결정할 수 없음
      • 프로그램이 어느 주소에 저장되어야하는지, 메모리를 어느정도 확보해야 하는지 결정할 수 없음
      • 등등등

대표적 운영체제

응용 프로그램과의 관계

  • 응용 프로그램을 실행시킨다
  • 응용 프로그램에 할당할 자원을 관리한다
    • 메모리, CPU 할당
  • 응용 프로그램 실행 권한을 관리한다
    • 모든 파일 삭제 막기 등
  • 응용 프로그램 사용자를 관리한다

폰 노이만 구조

Program이 Memory에 올라가고, CPU가 이를 가져와서 연산하는 형태
Memory 내에서 명령어 영역과 데이터 영역을 구분하지 않고 하나의 bus로 통신하기 때문에 병목현상이 발생함
이를 보완하기 위해 나온 것이 하버드 구조
하버드 구조는 명령어와 데이터 영역을 구분하고 이를 각각 다른 버스로 연결

현대 컴퓨터는 대부분 폰 노이만 구조이고, 하버드 구조를 사용하여 성능을 향상시킨 것도 있다고 한다(?)


부도덕한 시민은 도서관이 막고,
도서관 없이 책을 빌릴 순 없다

ls 같은 명령을 운영체제에 요청하고 기능을 제공해줌
응용 프로그램이 자원을 요청하면 OS가 자원을 응용프로그램에게 반환해줌
쉘도 하나의 응용 프로그램이다

OS는!
사용자에게 인터페이스 제공 == 쉘
사용자외에 응용프로그램에게도 인터페이스 제공 == API
- 함수로 제공
- 함수가 보통 많기 때문에 라이브러리 형태로 제공한다
- C Library 등
- 요청서 같은 것으로 봐도 좋다

쉘 또한 운영체제가 제공하는 API를 가지고 만들어진 것이다
쉘도 API를 통해 운영체제에 요청해서 자원을 가져온다

시스템 콜
API 내부에는 시스템콜이 있다!
시스템 콜을 래핑해서 각 언어에 맞게 제공하는 것 == API

OS는 시스템 콜을 제공한다
운영체제 입장에서 기능을 정의해놓은 것이라 프로그램에서 쓰기는 복잡하고, 사용법이 어렵다
각각의 API를 들어가보면 전부 시스템 콜
이 API를 기반으로 애플리케이션이나 쉘을 만들게 되는 것

Users
Application/Shell
Library OR API
System Call
Operating System
Hardware
CPU/Memory/Storage/Network

쉘 자체도 C 언어 같은 것으로 만들어진건가?
시스템콜을 호출하는 C라이브러리로 쉘을 만든다?

리눅스는 리눅스 자체가 C언어로 만들어져있고, C언어 자체에서 시스템콜을 바로 사용할 수 있다?

https://harryp.tistory.com/69


CPU도 여러 명령을 실행한다?
커널모드 = 특정한 자원에 접근해야해서

모드는 4가지가 있지만 대부분의 운영체제는 RING 3(사용자모드)와 RING 0(커널모드)만을 사용한다

OS 커널 = OS 본연의, 핵심 기능
커널모드 = OS가 CPU를 직접 쓸 떄 사용하는 모드

OS는 커널이고, 커널을 둘러싸고 사용자와 인터페이스하기 위한 껍데기 == 쉘

CPU 입장에서 명령어 수행할 때 모드를 확인한다?

사용자 영역에서 API를 통해 시스템콜을 호출하면, 운영체제로 들어간 뒤(커널모드가 된 뒤) CPU가 해당 명령을 실행한다?

  1. 1 ~ 1000까지 더하고
  2. 파일에서 데이터 가져와서
  3. 가져온 데이터와 1 ~ 1000까지 더한값을 다시 더하고 출력한다

어떤 명령은 사용자 모드에서 실행되고, 어떤 명령은 OS로 들어간 뒤 커널모드에서 실행된다
시스템 콜을 통과하는 순간 커널모드에서 실행된다(OS라는 특정 권한을 가지고 CPU에서 실행된다)

커널모드에서만 실행가능한 기능들은 반드시 시스템 콜을 사용해야 함(커널모드로 변경되어서 CPU에 그 명령을 실행해야함)

사용자모드와 커널모드 백단의 원리에는 CPU Protection RING이 있다

주민등록 등본은 동사무소에서 특별한 신청서를 써야만 발급된다

  • 동사무소 직원들은 특별한 권한을 가지고 등본 출력 명령을 실행한다

등본 신청 == 사용자모드
특별한 신청서 == 시스템콜
특별권한으로 주민등록 출력명령 실행 == 커널모드

응용 프로그래머 = 운영체제에서 제공하는 API를 가지고 응용프로그램을 만듦
시스템 프로그래머 = 운영체제, shell, API, system call 을 만들고 하드웨어도 조금 이해해야한다

리눅스는 c언어로 만들어져서 시스템콜 자체도 전부 c언어로 되어있다
그러므로 wrapping한 API를 사용하지 않고도 시스템콜 사용 가능
래퐂
읽혀진 데이터/결과값이 응용 프로그램으로 전달되면서 사용자모드로 전환됨

open이라는 함수는 unistd.h 라는 헤더파일에 저장되어 있음

시스템콜에 들어가면 시스템콜을 처리하는 운영체제 함수
시스템콜은 사실 사용자모드와 커널모드의 중간에 있다고 보면 된다


스케줄링

여러가지 응용 프로그램(프로세스)을 시간순서에 따라 CPU에 배치하는 방법

배치처리 시스템

  • 프로그램의 실행 요청 순서에 따라 순차적으로 프로그램을 실행하는 방식
  • 큐 방식과 비슷하다(FIFO)
  • 시간이 많이 걸리는 프로그램이 앞에 있을 경우 대기시간이 매우 길어지게 된다
    • app1이 12시간, app2가 30분 걸린다고 하면 app2는 12시간 30분을 기다려야함
    • 이런 특징 때문에 멀티 태스킹이 불가능하다

시분할 시스템

  • 큐에 들어온 프로그램들을 굉장히 작은 시간 단위로 쪼개서 수행함(시분할 시스템)
  • 이런 특징 때문에 멀티 태스킹이 가능함
  • 10ms ~ 20ms 정도로 시간을 쪼개면 사용자는 프로그램이 동시에 실행되는 것 처럼 느낌
    • e.g. MP3 프로그램을 실행하는 시점에 다른 프로그램들이 수행될 시간만큼 음악을 들을 수 있도록 음악을 미리 만들어 놓는다

멀티 태스킹과 멀티 프로세싱
멀티 태스킹은 단일 CPU에서 여러 프로그램을 실행하는 것이고, 멀티 프로세싱은 여러 CPU가 하나의 프로그램을 병렬로 실행해서 실행속도를 극대화 시키는 것

DMA

  • CPU는 프로그램에서 파일 IO가 필요할 경우, DMA라는 애한테 해당 작업을 요청하고 작업이 완료되면 DMA가 CPU에 인터럽트를 거는 방식으로 동작한다
  • CPU가 직접 디스크에 접근하여 파일을 읽을 경우, 디스크에서 읽는 시간을 CPU가 기다리는 것(blocking) 은 매우 낭비이다(CPU와 디스크의 수행시간 차이는 엄청나다)
  • 최신 컴퓨터 시스템/운영체제에서는 CPU가 모든 처리를 관장하면 아까우니까 디스크, 메모리 등은 DMA등과 같은 별도 칩이 다루고, CPU는 코드 실행에 집중토록 해서, 효율을 높였다로 이해했다

프로세스

  • 메모리에 올려져서 실행중인 프로그램을 프로세스라고 함
  • task, job 이라는 단어와 혼용해서 사용하기도 함
  • 응용 프로그램 != 프로세스
    • 응용 프로그램은 여러개의 프로세스로 이루어질 수 있다
    • 여러개의 프로세스가 상호작용하면서(통신하면서) 실행될 수도 있다
    • 서로 통신하는 프로그램을 작성할 수도 있다

스케줄러

  • 프로세스의 실행을 관리함
  • 여러가지 스케줄링 알고리즘이 존재함

FIFO 스케줄러

  • 특별한 작업없이 CPU를 처음부터 끝까지(들어온 순서대로) 쭉 실행한다
  • 가장 간단한 스케줄링 알고리즘이다(Queue의 FIFO)
  • 배치처림 시스템에 사용한다

최단 작업 우선(SJF) 스케줄러

  • 가장 실행시간이 짧은 프로세스부터 먼저 실행시킨다
  • 특정 시간내에 주어진 목적을 수행할 수 있도록 인터럽트 처리를 보장하는 운영체제(?)
    • 들어오는 프로세스들의 수행시간이 정확하게 예측이 가능하기 때문에 SJF 적용이 가능하다(?)
    • 다른 프로세스의 인터럽트가 들어오더라도 기존 프로세스는 주어진 시간내에 정확하게 실행되어야 한다(?)
    • 미사일 시스템 등
    • 언젠가는 읽어봐야할 글 http://blog.naver.com/linuxdude/120004460365

우선순위 기반 스케줄러

  • 프로세스마다 우선순위를 미리 지정하는 정적 우선순위
    • 현실적으로 어렵다
  • 상황에 따라 우선순위를 동적으로 변경하는 동적 우선순위
    • e.g. 오래된 프로세스는 우선순위를 높게 한다

Round Robin 스케줄러

  • 시분할 시스템을 기반으로 함
  • 큐에 있는 프로세스들을 정해진 시간만큼 분할해서 계속 수행함

프로세스 상태

CPU 사용량을 극대화하기 위해 프로세스의 상태를 이용한다

  • ready state
    • 실행을 기다리고 있는 프로세스들
  • running state
    • 실행중인 프로세스
  • block state
    • CPU가 아닌 다른곳에서 수행해야 할 작업(I/O 등)을 수행중인 프로세스
1
2
3
4
5
6
7
O는 CPU 연산이 필요한 시점, W는 다른 리소스 연산이 필요한 시점
시분할 시간 단위만큼 프로세스의 작업을 나눠놓은 형태이다

e.g.
1번 프로세스 O O
2번 프로세스 O O W W W O
3번 프로세스 O W W W O O
  1. 1,2,3 번 프로세스 모두 CPU 연산이 필요하므로 먼저 들어온 순서대로 ready state queue 쌓인다
  2. ready state queue에 있는 프로세스중 가장 첫번째 프로세스는 running state queue에 들어가서 실행되고, ready state queue 에서 빠진다
  3. 분할된 시간이 지났는데도 아직 프로세스의 작업이 남아 있을 경우 ready state queue로 다시 들어간다
    • 만약 다음 분할 작업이 W 연산이라면 해당 프로세스는 block state queue로 들어간다
    • block state queue에 있는 프로세스의 W 연산이 다 끝나면 인터럽트를 걸게되고, block state queue에 있는 프로세스가 다시 ready state queue로 들어간다
  4. 이 과정을 반복한다