Bit의 개발다이어리
article thumbnail

Chapter 09 운영체제 시작하기

운영체제operating system : 프로그램에 필요한 자원을 할당하고, 프로그램이 올바르게 실행되도록 돕는 프로그램. 운영체제의 지휘하에 컴퓨터 부품들이 작동합니다. 부서처럼, 부분마다 관리할 자원별로 기능이 나누어져 있습니다.
운영체제를 알면 운영체제의 에러메세지를 제대로 잘 이해할 수 있게 되므로 매우 중요합니다.
(시스템)자원 : 프로그램 실행에 필요한 요소들
커널영역kernel space : 컴퓨터 부팅 시, 운영체제가 적재되는 메모리 공간. 운영체제는 특별한 프로그램이기 때문에!
<-> 사용자 영역user space : 사용자가 이용하는 응용프로그램(특정목적을 위한 일반적인 프로그램) 적재
 
커널kernel : 운영체제의 핵심 서비스를 담당하는 부분. 프로세스 관리, 자원 접근 및 할당, 파일 시스템 관리
이중 모드 : CPU가 명령어를 실행하는 모드를 커널 모드와 사용자 모드로 구분하는 방식. 커널모드 전환하여 실행 후, 사용자모드 복귀 형태
커널 모드 : 운영체제 서비스를 제공받을 수 있는 실행 모드
응용 프로그램이 자원에 접근하기 위해서는 운영체제의 도움을 요청해야 합니다. = 운영체제 코드 실행

가상화를 제공하는 CPU라면 가상 머신을 위한 모드인 하이퍼 바이저 모드가 존재합니다.


시스템 호출system call : 운영체제 서비스를 제공받기 위한 요청
소프트웨어 인터럽트 : 인터럽트를 발생시키는 특정 명령어
 
프로세스process : 실행 중인 프로그램. CPU가 번갈아가며 프로세스들을 실행. 프로세스 동시 실행에 대비해 프로세스 동기화가 필수!
 
<운영체제가 자원별로 관리하는 방법>
CPU : 프로세스를 공정하게 CPU를 할당하기 위해 어떤 프로세스부터 CPU를 이용하게 할 것인가, CPU를 얼마나 오래 이용하게 할지를 결정 -> CPU 스케줄링
메모리 : 새로운 프로세스가 적재될 때마다 어느 주소에 적재할지 결정
입출력장치 : CPU가 하던일을 백업하고 운영체제가 인터럽트 서비스 루틴을 제공(인터럽트 처리)

파일 시스템 관리 : 디렉터리(폴더)로 관리

Chapter 10 프로세스와 스레드

프로그램 실행 전 -> 보조기억장치에 있는 데이터 덩어리

프로그램 메모리 적재 후 실행 -> 프로세스 생성.

 

포그라운드 프로세스foreground process : 사용자가 보는 앞에서 실행되는 프로세스

백그라운드 프로세스background process : 뒤편에서 실행되는 프로세스 -> 유닉스에서는 데몬, 윈도우에서는 서비스라고 부릅니다.

 

타이머 인터럽트(타임아웃 인터럽트) : 클럭 신호를 발생시키는 장치에 의해 주기적으로 발생하는 하드웨어 인터럽트. 타이머 인터럽트가 발생하면 프로세스는 차례를 양보하고 다시 기다립니다.

 

프로세스 제어 블록(PCB)Process Control Block : 프로세스 정보를 저장하는 자료구조. 커널영역에서 생성되며 실행이 끝나면 폐기됩니다. PCB에는 우선순위가 명시되어 있으며, 다음과 같은 정보들을 갖고 있습니다.

- 프로세스 ID : 프로세스 식별 고유 번호

- 레지스터 값 : 실행차례가 돌아오면 복원할 중간값들

- CPU 스케줄링 정보 : 언제, 어떤 순서로 CPU 할당받을지

- 메모리 관리 정보 : 프로세스가 어느 주소에 저장되어 있는지
- 사용한 파일과 입출력장치 목록 : 입출력장치나 파일을 사용하면 기록

 

문맥context : 하나의 프로세스 수행을 재개하기 위해 기억해야 할 정보.

문맥 교환context switching : 문맥을 PCB로부터 복구하여 새로운 프로세스를 실행. 여러 프로세스가 끊임없이 빠르게 번갈아가며 실행되는 원리이며, 너무 자주하면 오버헤드가 발생됩니다.

 

커널 영역에 PCB가 생성되는 반면, 사용자 영역에 프로세스가 배치됩니다.

영역들이 겹치지 않도록 힙 영역은 메모리의 낮은 주소->높은 주소로 할당되고, 스택 영역은 높은 주소->낮은 주소로 할당됩니다.

<정적 할당 영역> - 크기 고정

- 코드 영역code segment(텍스트 영역text segment) : 쓰기 금지(read-only), CPU가 실행할 명령어가 보관됩니다.

- 데이터 영역data segment : 프로그램 실행동안 유지할 데이터가 저장되는 공간. ex) 전역 변수.

<동적 할당 영역> - 크기가 변할 수 있습니다.

- 힙 영역heap segment : 프로그래머가 직접 할당하는 공간이며, 사용 후 반환! (메모리 누수memory leak : 반환하지 않아 메모리 낭비)

- 스택 영역stack segment : 데이터를 일시적으로 저장하는 공간. ex) 매개 변수, 지역 변수.

 

운영체제는 프로세스의 상태를 PCB로 인식하고 관리합니다. 하나의 프로세스는 여러 상태를 거쳐가며 실행됩니다.

- 생성 상태new : 프로세스 생성 중.

- 준비 상태ready : 당장 실행 가능하지만, 차례가 될 때까지 CPU 할당을 기다리는 상태

- 실행 상태running : CPU할당받아 실행 중인 상태. 타이머 인터럽트 발생 시 준비상태, 입출력 장치가 도중에 사용되면 대기상태로 갑니다.

- 대기 상태blocked : 프로세스 실행 도중 입출력장치를 사용한 경우. 입출력 완료 인터럽트를 받을 때까지 대기합니다. 입출력 작업 종료 시, 다시 준비상태로 돌아갑니다.

- 종료 상태terminated : 프로세스 종료된 상태. 운영체제는 PCB와 사용한 메모리를 정리합니다.

프로세스의 상태를 도표로 그린 것을 프로세스 상태 다이어그램process state diagram이라고 합니다.

 

운영체제는 프로세스가 프로세스를 낳는 구조입니다.

부모 프로세스parent process : 새 프로세스를 생성한 프로세스

자식 프로세스child process : 부모 프로세스 fork에 의해 생성된 프로세스. 부모프로세스의 자원들을 상속받습니다.(값과 위치는 다름)

exec를 통해 자신의 메모리 공간을 다른 프로그램으로 교체합니다.(덮어쓰기)

PPID(Parent PID) : 자식 프로세스의 PCB에 기록되는 부모 프로세스 PID

컴퓨터를 킨 순간에 생성된 최초의 프로세스가 나머지 프로세스들을 생성합니다.

부모와 자식 모두 exec(교체하여 덮어쓰기)를 하지 않을 경우, 같은 코드를 병행 실행하는 프로세스가 됩니다.

 

스레드thread : 프로세스를 구성하는 실행의 흐름 단위. 하나의 프로세스는 여러 개의 스레드를 가질 수 있습니다. 프로세스 자원을 공유하며, 실행에 필요한 최소 정보만으로 실행됩니다. 최근에는 CPU 작업 전달 시 프로세스 단위대신 스레드 단위로 많이 전달됩니다.

- 스레드 ID

- 레지스터 값(프로그램 카운터 값 등)

- 스택

으로 구성되어 있습니다.

 

단일 스레드 프로세스 : 실행의 흐름 단위가 하나

멀티 스레드 프로세스 : 실행의 흐름 단위가 여러 개. 여러 명령어 동시 실행 가능! But... 하나의 스레드에 문제 발생 시, 전체 프로세스에 문제가 발생될 수 있습니다.

헷갈리면 프로세스는 실행되는 프로그램이라고 생각하기! 프로세스는 기본적으로 자원 공유x(프로세스 간 통신IPC, 공유 메모리는 가능), 스레드끼리는 같은 프로세스 내에서 자원 공유.

+) 리눅스는 프로세스와 스레드를 구분하지 않고 '태스크'라고 부르고 있습니다.

 

Chapter 11 CPU 스케줄링

CPU 스케줄링 : 컴퓨터 성능과 직결되며, 어떤 프로세스를 할당하고 기다리게 할 지를 우선순위로 정합니다. 
입출력 집중 프로세스 I/O bound process : 실행 상태<대기 상태 기간

CPU 집중 프로세스 CPU bound process : 대기 상태<실행 상태 기간

 

아래의 두 가지가 반복됩니다.

CPU burst : CPU를 이용하는 작업 -> 많을수록 CPU 집중 프로세스.

I/O burst : 입출력장치를 기다리는 작업 -> 많을수록 입출력 집중 프로세스.

 

스케줄링 큐 scheduling queue : 프로세스들이 기다리는 줄.

준비 큐 ready queue : CPU를 이용하려는 프로세스들이 서는 줄.

대기 큐 waiting queue : 입출력장치를 이용하기 위해 대기 상태에 접어든 프로세스들이 서는 줄.

 

선점형 스케줄링 preemptive scheduling : 운영체제가 프로세스로부터 자원을 강제로 빼앗아 할당할 수 있습니다.

-> 골고루 자원 배분 가능. But, 문맥 교환 과정에서 오버헤드 발생 가능성

비전점형 스케줄링 non-preemptive scheduling : 먼저 자원을 이용 중인 프로세스가 있을 때, 스스로 대기 상태가 되기 전 까지는 끼어들 수 없습니다.

 

<CPU 스케줄링 알고리즘> 종류가 많아, 간단하게 키워드로 정리해보았습니다.

- 선입 선처리 스케줄링FCFS Scheduling : 비선점형. 호위효과(convoy effect)

- 최단 작업 우선 스케줄링Shortest Job First Scheduling : 비선점형이지만 선점형으로 구현가능. CPU 이용시간 가장 짧은 프로세스부터 실행.

- 라운드 로빈 스케줄링round robin scheduling : 선점형. 타임 슬라이스(CPU이용가능한 정해진 시간)만큼 돌아가며 CPU 이용. 이때, 타임 슬라이스 크기가 중요합니다. 너무 작으면 문맥 교환 발생 비용이 크고, 너무 크면 호위 효과가 생길 수 있습니다.

- 최소 잔여 시간 우선 스케줄링Shortest Remaining Time : 정해진 타임 슬라이스만큼 CPU사용하되, 다음 프로세스는 가장 작업 시간이 적은 프로세스.

- 우선순위 스케줄링priority scheduling : 우선 순위가 높은 프로세스 먼저 실행. -> 계속 순서가 미뤄지면 기아 현상starvation 발생 가능성. -> 이에 대비하여, 에이징aging기법으로 순위를 점차 높일 수 있다.

- 다단계 큐 스케줄링multilvel queue scheduling : 우선순위별로 준비 큐를 여러 개 사용. 우선순위 높은 큐를 먼저 처리하며, 이것이 비어 있다면 그다음 우선순위 큐의 프로세스들을 처리. 큐 마다 타임 슬라이스 개수, 스케줄링 알고리즘을 다르게 지정할 수 있습니다. 프로세스들이 큐 사이를 이동할 수 없으므로, 여전히 기아 현상이 발생할 여지가 있습니다.

- 다단계 피드백 큐 스케줄링multilevel feedback queue scheduling : 구현이 어렵지만 가장 일반적. 프로세스들이 큐 사이를 이동할 수 있습니다. 실행이 끝나지 않으면 다음 우선순위 큐에 삽입되므로, CPU를 오래 사용하면 점차 우선순위가 낮아집니다. 반대로 너무 오래 기다린다면 점차 우선순위를 높여(에이징 기법) 기아 현상을 예방!

숙제

profile

Bit의 개발다이어리

@bit비트

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!