Operating System(OS)
OS 정의
컴퓨터는 크게 하드웨어와 소프트웨어로 나뉜다. 소프트웨어는 또 응용 프로그램과 시스템 소프트웨어로 나뉜다. 응용 프로그램은 특정 작업을 위해 사용하는 프로그램이고, 시스템 소프트웨어는 컴퓨터 하드웨어와 응용 프로그램을 관리하기 위한 소프트웨어이다. 시스템 소프트웨어는 또 운영체제(OS)
와 유틸리티로 나뉜다. 운영체제란 컴퓨터 자원을 효율적으로 관리하고 응용 프로그램을 실행하기 위한 환경을 제공하는 소프트웨어이다. 유틸리티란 운영체제의 작업을 보조(바이러스 검사, 디스크 조각 모음, 압축 작업 등)하는 소프트웨어이다. 운영체제는 SW와 HW의 특성을 모두 가지므로 펌웨어(firmware)라고 한다.
역할과 목표
- 자원 관리(효율성) : 컴퓨터 자원을 응용 프로그램에게 효율 적으로 분배
- 자원 보호(안정성) : 악의적이거나, 잘못된 작업에 대해 컴퓨터 자원 보호
- 하드웨어 인터페이스 제공(확장성) : CPU, 메모리, 키보드 등 하드웨어를 플러그 앤 플레이로 쉽게 사용
- 사용자 인터페이스 제공(편리성) : GUI처럼 사용자가 운영체제를 쉽게 사용
OS 구조
OS 구조
Kernel
: 운영체제의 핵심 기능(프로세스, 메모리, 파일 시스템, 입출력, 프로세스 간 통신 관리)을 한다.- 시스템 호출(System Call) : 커널을 보호하며 커널의 기능을 제공하는 인터페이스이다. 안전하게 자원에 접근 가능하며, 운영체제는 그외에 자원 접근을 제한하여 컴퓨터 자원을 보호한다. 그러나 만약 응용 프로그램이 운영체제의 최상위 권한 모드인 커널 모드에 진입했을 경우 시스템 호출을 거치지 않고 자원을 직접 접근할 수 있다.
- Device Driver : 커널과 하드웨어 사이에 인터페이스를 통해 하드웨어를 조작한다. 시스템 호출과 달리 디바이스 드라이버는 커널의 일부만 감싸고 있다.
Interface
: 인터페이스는 사용자의 명령을 커널에게 전달하고 그 결과를 보여주는 역할을 한다. 인터페이스에는 명령줄 인터페이스(CLI)와 그래픽 인터페이스(GUI)가 있으며, 커널의 시스템 호출을 추상화한 API와 SDK가 있다.
커널의 종류
- 단일형 구조 커널(Monolithic Architecture) : 커널(Kernel)이 단일 모듈로 구성되어 있는 구조이다. 핵심 기능(메모리 관리자, 프로세스 관리자, 입출력 관리자, 네트워크 관리자, 프로세스 간 통신, 파일 시스템)들을 모듈로 구분하지 않았기 때문에 모듈 간 통신 비용이 없고 빠르지만, 결합도가 높기 때문에 버그나 오류를 찾기 어렵고, 결함이 시스템 전체에 퍼질 수 있으며, 새로운 환경에 적용하기 어렵다는 단점이 있다.
- 계층형 구조 커널(Layered Architecture) : 유사한 기능의 모듈들을 하나의 계층으로 묶어 계층 별로 분리한 구조이다. 입출력 관리자-메모리 관리자-프로세스 관리자 순으로 배치되어 있다. 단일형 구조에서 발전한 형태로 버그나 오류를 수정하기 쉽다. 윈도우 운영체제가 이 구조이다.
- 마이크로 구조 커널(Micro Architecture) : 최소한의 기능(프로세스 관리, 메모리 관리, 프로세스 간 통신)만 커널이 제공하는 구조이다. system call과 나머지 기능 모듈들(파일 시스템, 프로세스 관리자, 하드웨어 관리자)은 사용자 영역에 존재한다. 이 구조에서는 각 모듈이 독립적으로 작동하기 때문에
- 가상머신(virtual machine) : 다른 컴퓨터 시스템을 소프트웨어적으로 모방하여 실행하는 환경이다. 예를 들어 자바 가상 머신이 있다.
운영체제 종류와 발전과정
종류
- Unix : 단순하고, 이식하기 쉬운 운영체제이다. 오픈소스가 되면서 여러 버전이 나왔다.
- Linux : 리누스 토발즈가 만든 PC에서 동작하는 유닉스 호환 커널이다.
- MacOS : 마하 커널 기반의 최초의 GUI를 도입한 운영체제
- IOS : MacOS를 수정한 OS로 모바일 전용 운영체제이다.
- Window : 마이크로소프트가 MacOS를 보고 만든 GUI 운영체제
- Android : 구글에서 개발한 모바일 전용 운영체제이다. 리눅스 커널과 자바를 사용해 호환성이 뛰어나다.
발전과정
- 에니악(1940년대) : 하드 와이어링 방식으로 논리회로를 구성하는 최초의 컴퓨터로 운영체제가 없다
- 천공카드(1950년대) : 일괄 작업 시스템 방식의 운영체제
- 대화형 시스템(1960년대) : 키보드와 모니터 사용
- 시분할 시스템(1960년대) : 멀티 프로그래밍으로 하나의 cpu로 여러 작업을 동시에 실행하는 것처럼
- 분산 시스템(1970년대) : 여러 컴퓨터를 네트워크로 연결해 작업을 처리
- 클라이언트/서버 시스템(1990년대)
- P2P 시스템, 클라우드 컴퓨팅, 사물 인터넷(2000년대)
- 자료구조 스택과 큐 기능
Computer Structure
기본 지식
컴퓨터는 필수장치인 CPU와 메인메모리, 주변장치인 입출력 장치, 저장장치로 나뉟다.
CPU(중앙처리장치)
:메인 메모리(주기억장치)
: 현재 실행 중인 프로그램과 데이터를 저장하는 휘발성 메모리이다. 보통 메모리는 메인 메모리를 가리키며 제1저장장치로도 불린다.입출력장치
: 입력과 출력을 담당보조저장장치
: 데이터를 영구적으로 저장할 수 있는 비휘발성 메모리(ROM)로 용량이 크고 값이 싸지만, 메모리보다 속도가 느리다. 제2저장장치로도 불린다.메인보드
: CPU와 메모리 등의 장치를 버스로 연결하고 전원을 공급해주는 판버스
: 장치들을 연결하여 데이터를 이동시키는 통로- 시스템 버스(전면버스,FSB) : 컴퓨터 장치를 연결하는 버스, 메인보드의 동작 속도임
- CPU 버스(후면버스,BSB) : CPU 내부 장치를 연결하는 버스, CPU 클록의 속도이며 FSB보다 빠름
bit(b)
: 컴퓨터에서 데이터의 표시 단위. 8b = 1B(Byte)이다. 바이트는 B, KB, MB, GB, TB, PB 순으로 커지며 각 단위당 2^10배의 차이가 난다. 그리고 바이트의 크기를 10진법으로 알기 쉽게 표현하기 위해 대략 2^10=1024≒1000으로 계산하여 각 바이트 단위 당 1000배의 차이가 나는 것으로 표현하기도 한다.clock
: 컴퓨터의 모든 장치의 작업을 동기화 시키는 일정한 신호인 클록 틱(또는 펄스)을 만드는 장치이다. CPU도 클록에 맞추어 작업을 하는데 헤르츠(Hz)로 CPU의 성능을 나타낼 수 있다. 헤르츠는 1초동안 몇 번의 몇번의 클록 틱이 발생했는지이다.word
: CPU가 한번에 처리 가능한 데이터의 크기이다. 레지스터 하나의 크기, 버스의 대역폭(bandwidth)와 같은 값이다.컴파일러
: 소스코드를 컴파일하여 기계어로 변역한 실행 파일을 만드는 프로그램이다.인터플리터
: 실행 파일을 만들지 않고 소스 코드를 한줄씩 해석해 실행한다.폰노이만 구조
: CPU, 메인 메모리, 입출력장치, 저장장치가 버스로 연결되어 있는 구조이다. 폰 노이만 구조는 프로그램과 데이터가 같은 형태의 이진 코드로 저장장치에 저장되며, 프로그램이 메모리에 올라와야 CPU가 실행가능하다는 특징이 있다. 폰노이만 구조는요리사 모형
으로 설명 가능하다. 요리사 모형에는 요리사(CPU), 도마(메인 메모리), 보관창고(저장장치)가 있다. 요리사는 보관창고에서 재료를 꺼내 도마에 올리고 요리를 하며, 요리방법 결정(프로세스 관리), 도마 정리(메모리 관리), 보관창고 정리(저장장치 관리)를 한다. 만약 도마가 요리를 방해할 만큼 작으면 요리를 하는데 오래 걸리는 것처럼 메모리 크기가 일정 수준이하로 작으면 컴퓨터 작업 속도가 떨어진다.
CPU
CPU 구조
산술논리 연산장치(ALU)
: 산술연산(+,-,*,/)과 논리연산(AND, OR)을 수행제어장치(CU)
: 작업을 지시레지스터(Register)
: CPU 내부의 위치한 고속의 메모리로 작업에 필요한 데이터를 저장- 사용자 가시 레지스터 : 산술논리 연산장치가 이용하며, 사용자 프로그램에 의해서 값이 변경됨
데이터 레지스터(DR)
: 메모리에서 가져온 데이터를 임시 저장한다. CPU에 있는 대부분의 레지스터로 일반 레지스터 또는 범용 레지스터로 불린다.주소 레지스터(AR)
: 데이터나 명령어가 저장된 메모리의 주소를 저장한다.
- 특수 레지스터 : 사용자가 임의로 변경할 수 없음
프로그램 카운터(PC)
: 다음에 실행할 명령어의 주소를 저장한다. 명령어 포인터 라고도 불린다.명령어 레지스터(IR)
: 현재 실행중인 명령어를 저장한다. 제어장치가 IR의 데이터를 해석후 외부 장치에 신호를 보낸다.메모리 주소 레지스터(MAR)
: 주소버스와 연결되어 접근할 메모리에 데이터의 주소를 저장한다.메모리 버퍼 레지스터(MBR)
: 데이터버스와 연결되어 가져오거나 보낼 데이터를 임시저장한다.프로그램 상태 레지스터(PSR)
: if문 분기에 사용되며, 플래그 레지스터, 상태 레지스터, 컨디션 레지스터라고도 불린다.
- 사용자 가시 레지스터 : 산술논리 연산장치가 이용하며, 사용자 프로그램에 의해서 값이 변경됨
CPU에서 프로그램 실행 과정
- 프로그램이 시작되면 PC에 프로그램의 시작 주소가 저장된다.
- PC의 주소에 해당하는 명령어를 IR에 저장한다.
- IR해석하여 데이터를 받아오거나 연산을 하는 작업을 한다.
- 2,3을 반복한다.
버스
버스는 시스템 버스와 CPU내부 버스로 나뉜다. 시스템 버스에는 3가지 종류가 있다.
제어 버스(control bus)
: CPU의 제어장치가 어떤 장치에게 내린 제어 신호가 이동하는 통로이다. 신호를 받은 장치는 작업을 완료했거나 오류가 발생했다는 결과를 CPU로 전송해야하기 때문에 양방향이다.주소 버스(address bus)
: MAR과 연결된 버스로 단방향이다.데이터 버스(data bus)
: MBR과 연결된 버스로 양방향이다.
버스에서 한번에 이동가능한 데이터의 크기인 버스의 대역폭(bandwidth)이 클수록 속도가 빠르다.
메모리
메모리는 운영체제 영역과 사용자 영역으로 나뉜다. 프로그램은 각자의 사용자 영역을 사용하는데 어떤 프로그램이 다른 프로그램의 사용자 영역을 침범하지 않도록 메모리 보호를 해야한다. 프로그램이 CPU를 사용중이면, 운영체제의 작업이 중단되므로 하드웨어의 도움을 받아야한다. 이때 경계 레지스터
와 한계 레지스터
를 사용한다. 경계 레지스터는 현재 진행 중인 메모리의 시작 주소를 저장하고, 한계 레지스터에 마지막 주소까지의 차이, 즉 크기를 저장한다. 만약 작업 중에 두 레지스터 값을 벗어났으면 CPU는 작업을 중단시키고 운영체제에게 인터럽트 신호를 보내 운영체제는 해당 작업을 강제 종료시킨다.
다음은 메모리의 종류이다.
- 휘발성 RAM(volatility RAM)
- DRAM(Dynamic RAM) : 전력이 공급되도 일정 시간이 지나면 사라져 재생이 필요
- SRAM(Static RAM) : 전력이 공급되는 동안 데이터 보관
- SDRAM(Synchronous Dynamic RAM) : 클록틱 발생마다 데이터를 저장하는 동기 DRAM
- DDR(Double Data Rate) SDRAM : SDRAM의 입출력 속도를 높인것
- 비휘발성 RAM(non-volatility RAM)
- 플래시 메모리 : 전력없이 데이터 보관. 각 소자당 최대 사용횟수 있음 e.g. sd 카드, usb
- FRAM
- PRAM
- SSD : 빠른 속도, 저전력, 높은 내구성으로 하드디스크를 대신하여 쓰임
- ROM : 데이터를 한번 저장하면 바꿀 수 없어 바이오스를 저장하는 용도
- 마스크 롬 : 데이터를 지우거나 쓸 수 없음
- PROM : 전용 기계를 사용해 한번만 저장 가능
- EPROM : 플래시 메모리처럼 사용가능하나 가격이 비쌈
부팅
운영체제 또한 응용 프로그램처럼 메모리에 올려서 실행을 한다. 이때 운영체제를 하드디스크에서 메모리에 올리는 과정을 부팅
이라고 하고, 이를 ROM에 저장된 바이오스
가 실행시킨다. 바이오스는 더불어 CPU, 메모리, 하드디스크 등 하드웨어가 정상적으로 작동하는지 확인한다. 하드웨어 점검을 완료하면 하드디스크에 마스터 부트 레코드(MBR)에 저장된 부트스트랩
을 메모리로 가져와 실행한다. 부트스트랩이란 하드디스크에 저장된 운영체제를 메모리로 가져와 실행하는 역할을 하는 프로그램이다.
컴퓨터 성능 향상 기술
buffer
: 일정량의 데이터를 모아서 옮겨 두 장치의 속도 차이를 완화하는 장치이다.SPOOL
: 입출력 작업을 대기열 형태로 처리하여 CPU와 입출력 장치가 독립적으로 동작하게하는 소프트웨어적인 버퍼이다.cache
: CPU가 앞으로 사용할 것으로 예상되는 메모리의 데이터를 미리 가져와(prefetch) 메모리(FSB)와 CPU(BSB) 간의 속도 차이를 완화하는 임시저장소이자 버퍼의 일종이다. 캐시는 CPU 내부 버스 속도로 작동하므로 빠르다. 캐시의 데이터를 CPU가 실제로 사용하면 cache hit라고 하며, 사용하지 않았을 때는 cache miss라고 한다. 캐시 히트가 되는 비율인 캐시 적중률은 보통 90%이다. 캐시 적중률을 높이는 방법은 캐시의 크기를 키우거나, 지역성 이론에 따라 가까운 데이터를 가져오는 법이 있다. 또한 캐시가 데이터를 가져왔는데 메모리에서 변경이 될때 이를 반영해야한다. 여기에 즉시쓰기와 지연쓰기 방법이 있다. 즉시쓰기 방법은 메모리의 최신값이 항상 유지되지만 빈번한 데이터 전송으로 성능이 느리다는 단점이 있다. 지연쓰기는 변경된 내용들을 모아 주기적으로 반영하는 방법이다. 즉시쓰기에 비해 성능은 향상되지만 데이터의 불일치가 발생할 수 있다는 단점이 있다. 캐시는 두개의 레벨로 나뉘는데 메모리에서 어떤 자료든 상관없이 가져오는 일반 캐시(L2 캐시)와 명령어와 데이터를 구분하여 저장하는 특수 캐시(L1 캐시)이다. 특수 캐시는 명령어 캐시와 데이터 캐시로 나뉘며 각각 IR과 DR에 연결되어 있다.저장장치 계층구조(storage hierarchy)
: 저장장치들을 속도 순으로 배치시킨 구조이다. 속도가 가장 빠른 저장장치는 CPU 근처에 배치되며 레지스터-캐시-메모리-저장장치 순으로 배치된다. 보통 저장장치의 속도가 빠르면 가격이 비싸 용량이 적다. 이 구조를 사용하면 속도는 레지스터처럼 빠르면서 용량은 저장장치처럼 크게 컴퓨터를 동작시킬 수 있다. 문제는 중복되는 데이터의 일관성을 유지시키는 것이다. 데이터 일관성이 틀려지는 경우는 지연쓰기를 사용하거나, 동시에 같은 데이터에 같은 프로세스가 접근하거나, 갑자기 전원이 꺼지거나, 버퍼를 비우지 않았는데 하드웨어를 제거하는 경우이다.interrupt
: CPU의 작업과 입출력장치의 작업을 독립적으로 운영하는 방식이다. 과거에는 CPU가 작업을 일일이 지시하는 polling 방식을 사용했기 때문에 CPU의 효율이 떨어졌다. interrupt 방식의 과정은 외부장치에게 명령을 보내면 장치가 독립적으로 작업을 실행하고 그 결과를 CPU에게 완료 신호인 interrupt를 보내는 것이다. CPU는 interrupt를 받으면 작업을 중단하고 이벤트를 처리한다. interrupt가 자주 발생되면 비효율적이므로 interrupt의 배열인 interrupt vector를 사용한다. 또한 interrupt를 어떤 장치가 보냈는지에 대한 장치 고유 번호인 interrupt number가 있다. 이는 운영체제마다 다르며 window에서는 인터럽트 번호를 IRQ라고 부르며 키보트는 1번, 마우스는 12번 등으로 구분한다.직접 메모리 접근(DMA)
: 폴링에서 인터럽트 방식으로 바뀌면서 입출력관리자가 데이터 입출력을 하기위해 메모리 직접 접근할 수 있는 권한이다. CPU가 입출력관리자에게 입출력 요청을 보내면 입출력관리자는 DMA 권한을 부여받는다.메모리 맵 입출력
: 메모리 공간을 CPU가 사용하는 부분과, 직접 메모리 접근으로 들어오거나 나가는 데이터를 저장하는 부분으로 분리하는 것이다. 따라서 메모리 공간은 운영체제 영역, CPU 작업 영역, 입출력 작업 영역으로 나뉘게 된다.사이클 훔치기
: CPU와 DMA가 동시에 메모리에 접근하면 DMA가 우선적으로 메모리를 사용한다. 그 이유는 입출력장치의 속도가 CPU보다 느리기 때문이다.
Process, Thread
프로세스 개요
프로그램은 저장장치에 저장된 정적인 상태이고 프로세스
는 실행을 위해 메모리에 올라온 동적인 상태이다. 프로세스가 생성되면 동시에 프로세스의 정보를 담고 있는 프로세스제어블록(PCB)
이 만들어진다. PCB는 운영체제 영역에 올라가고, 프로세스는 사용자 영역에 올라간다. 운영체제 또한 프로그램이기 때문에 응용 프로그램과 섞여서 메모리에 올라간다. PCB는 프로세스가 종료되면 삭제된다. 메모리에 올라온 프로세스는 CPU를 할당받아 처리가 되는데 처리하는 방식으로 대표적으로 두 가지가 있다.
일괄 작업 방식(batch-job)
: 프로세스들이 하나씩 처리되는 방식으로 큐로 구현된다.시분할 방식(time-sharing)
: 프로세스들의 실행시간을 분배하여 돌아가며 처리하는 방식이다.
프로세스 상태
프로세스에는 상태가 있다. 일괄작업시스템은 단순히 순서대로 생성,실행,완료상태인 반면, 시분할시스템은 기본적으로 생성,준비,실행,완료상태를 갖고 추가로 보류,대기상태가 있다. 다음은 프로세스에 대한 용어이다.
CPU 스케줄러
: 프로세스를 효율적으로 실행시키기 위해 프로세스의 상태를 관리하는 것타임 슬라이스(타임 퀸텀)
: 프로세스에 배당된 작업시간. 시간이 끝나면 클록으로부터 인터럽트 발생. 문맥교환 시간을 고려하여 결정.생성상태
: 프로그램이 메모리에 올라와 PCB를 할당받은 상태.준비상태
: 준비 큐에서 실행을 기다리른 상태.실행상태
: 프로세스가 CPU를 할당받아 실행중인 상태.대기상태
: 실행상태의 프로세스가 입출력을 요청할때 인터럽트가 발생할때까지 기다리는 상태. 작업의 효율을 높이기 위해 만들어짐.완료상태
: 프로세스가 종료되어 자원을 반납하고 메모리에서 삭제되는 상태. 만약 어떠한 이유로 강제종료를 하면 직전 메모리 상태를 저장장치로 옮기는 코어덤프 실행.타임아웃
: 타임 슬라이스가 끝나 실행상태에서 준비상태로 바꾸는 작업디스패치
: 준비상태에서 실행상태로 바꾸는 작업. 타임아웃 이후에 일어남.문맥교환(context change)
: 타임아웃과 디스패치가 일어날때 또는 인터럽트가 발생했을때 두 프로세스의 PCB를 교환하는 작업.휴식상태
: 작업을 쉬고있는 상태. 멈춘 지점부터 재시작(resume)가능.보류상태
: 메모리에서 하드웨어의 swap영역으로 쫓겨나 작업을 ‘일시정지’한 상태. 메모리가 꽉 찰 때, 오류가 발생했을 때, 악의적인 공격을 한다고 판단되었을 때, 매우 긴 주기로 반복되는 프로세스인 경우, 대기상태에서 입출력이 지연될 때 보류상태로 전환됨. 보류상태는 재시작하여 다시 기존의 상태로 돌아갈 수 있음.- 보류준비상태 : 준비상태에서 보류된 프로세스의 상태
- 보류대기상태 : 대기상태에서 보류된 프로세스의 상태. 입출력이 완료되면 보류준비상태로 이동.
활성상태
: 보류상태 이외에 상태
PCB와 프로세스 구조
PCB 구조
- 포인터 : 대기상태나 준비상태를 구현할때 사용되는 큐를 구현하기위한 다음 PCB의 주소를 저장
- 프로세스 상태 : 생성, 준비, 실행, 대기, 보류준비, 보류대기 등
- 프로세스 구분자(PID) : 프로세스 아이디
- 프로그램 카운터(PC) : 레지스터의 PC와 같은 역할
- 프로세스 우선순위 : 디스패치의 기준
- 각종 레지스터 정보 : 프로세스가 CPU를 할당받았을 때 레지스터에서 사용한 중간값 저장
- 메모리 관련 정보 : 프로세스의 메모리 주소, 경계레지스터, 한계레지스터 또한 세그먼테이션 테이블, 페이지 테이블 등의 정보 저장
- 할당된 자원 정보 : 프로세스가 사용중인 컴퓨터 자원 정보
- 계정 정보 : 계정 번호, CPU 할당 시간, CPU 사용 시간 등
- PPID와 CPID : fork()가 호출되었을때 부모 또는 자식 PID를 저장
프로세스 구조
코드 영역(텍스트 영역)
: 프로그램의 코드가 기술된 영역. 읽기 전용.데이터 영역
: 사용하는 변수와 파일 등의 데이터를 저장. 읽기 쓰기 가능. const는 쓰기 불가능. 일반 데이터 영역과 힙영역으로 나뉨스택 영역
: 실행하는데 부수적인 정보를 저장. 예를들어 함수 호출 후 복귀 위치를 저장. 운영체제가 관리하는 영역으로 사용자는 볼 수 없음.
프로세스의 연산
다음은 프로세스의 연산이다.
fork()
: 실행중인 프로세스를 복사하는 시스템 호출. 원본 프로세스는 부모 프로세스, 생성된 프로세스는 자식 프로세스인 부모-자식관계. 부모 프로세스, 자식 프로세스의 차이는 PID, PPID, CPID. fork()의 장점은 프로세스의 생성 속도가 빠르고, 부모 프로세스의 자원을 추가 작업없이 상속받을 수 있고, 자식 프로세스 종료 후 사용중인 자원을 부모 프로세스가 정리할 수 있어 시스템 관리를 효율적으로 할 수 있다는 점.exac()
: 기존 프로세스를 새로운 프로세스로 전환하는 시스템 호출. 보통 fork와 같이 사용하여 새로운 프로세스를 만들고 exac()으로 내용을 바꾼다. exac()이 실행되면 프로세스의 코드영역, 데이터영역이 바뀌고, 스택영역, 프로그램 카운터 및 각종 레지스터 값이 모두 초기화된디. exac()의 장점은 프로세스의 구조를 재활용해 속도가 빠르고, fork와 연계했을 때 부모-자식 관계를 사용할 수 있어 시스템 관리를 효율적으로 할 수 있다는 것이다.
fork()와 exac()으로 프로세스의 계층 구조
를 만들 수 있다. 유닉스
에서 커널이 처음 메모리에 올라와 부팅되면 root 프로세스 아래에 page daemon, swapper, init
프로세스를 만든다. 그중에 init 프로세스는 나머지 전체 프로세스의 출발점이다. init의 자식 프로세스들은 트리 형태로 구성되며 init의 자식은 기본적으로 login
과 shell
이 있다. login은 사용자가 컴퓨터에 접속했을 때 인증하는 프로세스이다. login이 통과되면 exac()을 호출해 shell로 전환한다. 이는 운영체제에 명령을 내리고 결과를 받을 수 있는 프로세스이다. shell은 fork(), exac()으로 응용 프로그램을 자식 프로세스로 만들어 실행한다.
프로세스 계층 구조의 장점으로 여러 작업을 동시에 처리가능하고, 부모-자식 관계로 자원의 회수가 용이하다는 점이 있다.
하지만 자식 프로세스가 종료되기 전에 부모 프로세스가 먼저 종료되었을 때 자식 프로세스는 고아 프로세스
가 되고, 부모 프로세스가 종료된 자식 프로세스의 자원을 정리하지 않았을 때 자식 프로세스는 좀비 프로세스
가 된다. c언어에서 main() 함수의 끝에 return 0 또는 exit(0)을 쓰는 이유도 부모 프로세스에게 작업이 끝났음을 알리기 위함이다. 위에 문자을 안썼다고 무조건 좀비 프로세스가 되는 것은 아니지만 자원을 정리하거나, 자식 프로세스와 동기화할 수 있다.
스레드
스레드
란 프로세스의 코드에 정의된 절차에 따라 CPU에 작업 요청을 하는 실행단위이다. 운영체제 입장에서 작업단위는 프로세스, CPU입장에서는 스레드.
프로세스와 스레드의 차이는 프로세스는 실행 순서가 중요하지 않지만, 스레드는 프로세스에 정의된 순서대로 실행되어야 한다.
멀티태스크와 멀티스레드차이 : 멀티태스크는 여러 프로세스, 멀티 스레드는 프로세스안에 여러 스레드
- 멀티스레드 : 프로세스 내 작업을 여러개의 스레드로 분할하는 기법
- 멀티태스킹 : 운영체제가 스레드에 시간을 잘게 나누어 CPU에게 작업을 주는 기법. 시분할 시스템에서 CPU의 작업단위는 스레드
- 멀티 프로세싱 : 여러 개의 CPU를 사용하거나 하나의 CPU 내에 여러 개의 코어를 만드는 작업환경
- CPU 멀티 스레드 : 하나의 CPU에서 스레드를 잘게 나누어 동시에 처리
멀티스레드 탄생 배경 기존 멀티 태스킹의 fork(), exac()으로 프로세스를 만드는 것은 불필요한 작업이 많고 메모리 낭비가 심했음. 따라서 한 프로세스 안에서 코드 영역과 데이터 영역은 공유하고, 스택 영역에 여러개의 스레드를 만드는 멀티 스레드방식을 사용. 스레드는 가벼운 프로세스, 스레드가 하나인 프로세스는 무거운 프로세스. 멀티스레드의 예로 자바의 스레드 라이브러리를 사용하여 멀티스레드를 만들 수 있음.
멀티스레드 장점
- 응답성 향상 : 한 스레드가 입출력으로 대기해도 다른 스레드는 실행가능
- 자원공유 : 스레드 간에
- 효율성 향상 : 불필요한 자원의 중복을 막음
- 다중 CPU 지원 : CPU가 여러개 있다면 스레드를 동시에 처리
단점
- 자원공유 : 한 스레드에 문제가 생기면, 다른 스레드에 영향 인터넷 익스플로어는 멀티스레드여서 한 탭이 문제가 생기면 인터넷익스플로어 전체가 종료, 크롬은 멀티태스킹이어서 하나가 문제 생겨도 강종X
스레드 종류
- 커널 스레드
- 사용자 스레드
멀티스레드 모델
- 사용자 스레드(1 to N 모델)
멀티 프로세싱
멀티 프로세서 시스템
: 프로세서를 여러개 사용하는 시스템. 프로세서마다 레지스터와 캐시를 가지며 모든 프로세서가 시스템 버스를 통해 메인 메모리를 공유. 장점은 많은 작업을 동시에 실행시킬 수 있음
멀티코어 시스템
: 기존 시스템을 유지한 채 멀티 프로세싱을 할 수 있게 하는 시스템. 하나의 칩에 CPU의 코어를 여러 개 만들어 여러 작업을 동시 처리.
명령어 병렬 처리
: 파이프라인 기법으로 하나의 CPU에서 스레드의 명령어 패치, 명령어 해석, 실행, 쓰기 과정을 동시에 진행하는것
CPU 멀티 스레드
: 여러 개의 스레드를 동시에 처리
현대의 CPU는 하나의 칩에 멀티코어와 명령어 병렬 처리 기능을 동시에 구현
CPU 관련 통용 법칙
- 무어의 법칙 : CPU 속도가 24개월마다 2배 빨라짐
- 암달의 법칙 : 주변장치 향상없이 CPU성능을 높여도 컴퓨터 성능을 높일 수 없음
동적 할당 영역과 시스템 호출
CPU Scheduling
스케줄링 종류
선점형
/비선점형
: CPU를 빼앗을 수 있다 / 빼앗을 수 없다.
프로세스 우선순위
우선순위 높음 | 우선순위 낮음 | 이유 |
---|---|---|
커널 |
일반 |
운영체제의 핵심 기능이기 때문 |
전면 |
후면 |
GUI가 빨라야 사용자 편의성이 향상되기 때문 |
입출력 집중 |
CPU 집중 |
입출력 집중은 CPU 사용 시간이 짧기 때문 |
프로세스의 중요도는 프로세스 제어 블록에 표시되는데 이 우선순위는 준비상태의 다중 큐
로 처리된다. 우선순위의 개수 만큼 큐가 있으며, 해당하는 우선순위의 큐에 프로세스가 들어간다. 프로세스가 우선순위를 배정하는 방식은 고정 우선순위 방식과 변동 우선순위 방식으로 나뉜다. 이 방식은 작업 중간에 프로세스의 우선순위를 고정할지 변동할지를 말하는 것이다. 변동 우선순위 방식은 효율은 좋지만 구현하기 어렵다. 예를들어 우선순위가 낮지만 중요한 자원을 사용중일때 우선순위를 높이면 CPU를 더 자주 할당받아 작업을 빨리 끝낼 수 있다.
대기 상태에서도 다중 큐를 사용한다. 대기 상태는 입출력을 기다리는 프로세스들이 모여있는 곳으로, 입출력 장치의 개수만큼 큐가 존재한다. 여기서 입출력 장치에는 HDD, CD-ROM, LAN 등이 있다. 준비 큐와 대기 큐의 차이점은 준비 큐는 한번에 하나의 프로세스를 꺼내어 CPU에 할당하고, 대기 큐는 여러개의 PCB를 꺼내 준비상태로 옯긴다는 것이다.
스케줄링 알고리즘 종류
스케줄링 알고리즘의 평가기준은 다음과 같다.
- CPU 사용률: 전체 CPU 동작 시간 중 CPU가 사용된 시간, 100%가 이상적
- 처리량 : 단위 시간당 작업을 마친 프로세스 수
- 대기 시간: 프로세스가 작업 시작 전까지 대기하는 시간
- 응답 시간: 프로세스 시작 후 첫번째 출력또는 반응이 나올때까지 거리른 시간
- 반환시간 : 프로세스 시작 후 종료되고 자원을 반환하는 데까지 걸리는 시간, 대기시간+실행시간
CPU 사용률과 처리량은 계산하기 어려우므로 보통 나머지 3개의 평가 방식을 사용한다. 평균 대기시간은 모든 모든 프로세스 대기 시간을 합한뒤 프로세스 수로 나눈 값이다. 평균 대기 시간은 알고리즘의 절대적인 성능을 보여주지는 않는다.
FCFC(First Come First Served) 스케줄링
이란 우선순위 없이 준비 큐에 도착한 순서대로 CPU를 할당하는 비선점형 방식이다. 이 방식은 프로세스의 처리 기간이 길면 다른 프로세스들은 기다린다는 단점이 있다. 이처럼 컨베이어 벨트에 작업물이 한줄로 늘어서 앞의 작업이 오래 걸려 뒤의 작업 지연되는 것 같다하여 이를 콘보이 효과라고 한다.
SJF(Short Job Rirst) 스케줄링
준비 큐에 있는 프로세스 중에서 실행시간이 가장 짧은 방식부터 CPU에 할당하는 비선점형 방식으로 최단 작업 우선 스케줄링 이라고도 한다. 이 방식은 콘보이 효과를 완화하여 보통 FCFC보다 평균 대기시간이 짧다. 하지만 운영체제가 프로세스의 종료 시간을 정확하게 예측하기 어렵다는 점, 공평성에 위배되어 아사현상, 무한 봉쇄 현상을 일으킬 수 있다는 점이다. 후자에 대한 해결책으로 aging(나이먹기)가 있다. 이는 프로세스가 양보하는 상한선을 정하는 것이다. 이 스케줄링 방식은 위와 같은 문제로 잘 사용하지 않는다.
HRN(Highest Response Ratio Next) 스케줄링
SJF의 아사현상을 에이징으로 해결하는 비선점형 알고리즘으로 최고 응답률 우선 스케줄링 이라고도 한다. 이 방식은 서비스를 받기 위해 기다린 시간과 CPU 사용시간을 고려하여 스케줄링하는 방식이다. 프로세스의 우선순위를 정하는 기준은 (대기시간+CPU사용시간)/CPU사용시간이다. 하지만 여전히 공평성이 위배되어 많이 사용되지 않는다.
RR(Round Robin) 스케줄링
프로세스에게 할당된 타임 슬라이스가 끝나면 준비 큐로 이동시키는 선점형 방식이다. 이 방식은 우선순위를 적용하지 않는 가장 단순한 스케줄링 방식이다. 이 방식은 FCFS의 평균 대기 시간보다 작거나 같은데, 만약 같으면 FCFS보다 비효율적이다. 왜냐하면 선점형 방식은 문맥 교환 시간이 추가되기 때문이다.
SRT(Shortest Remaining Time) 스케줄링
SJF와 RR을 혼합한 선점형 방식으로 최소 잔류 시간 우선 스케줄링이라고도 한다. 타임 슬라이스가 있으며, 우선순위는 남은 작업 시간이 가장 적은 프로세스 순으로 선택한다. 이 방식은 평균 대기 시간이 위에 방식들보다 작지만, SJF에는 없는 문맥교환시간이 추가되고, 종료시간은 예측하기 어려우며, 아사 현상이 발생한다는 단점이 있어 잘 사용되지 않는다. 다시말해 SJF와 RR의 단점을 모두 가지고 있다는 것이다.
우선순위 스케줄링
어떤 기준으로 우선순위를 정하느냐에 따라 다양하게 구현이 가능하다. 이 방식은 프로세스의 순서를 무시하고 우선순위가 높은 프로세스에 먼저 CPU를 할당하므로 공평성을 위배하고 아사현상을 일으킨다는 공통적인 문제가 있다. 또한 우선순위를 매번 바꾸어야 하므로 오버헤드가 발생해 시스템의 효율성이 떨어진다.
다단계 큐 스케줄링(MLQ, Multi-Level Queue)
우선순위에 따라 준비 큐를 여러개 사용하여 운영체제는 프로세스에 우선순위를 매겨 해당 우선순위 큐에 삽입하는 방식이다. 우선순위는 프로세스가 큐에 삽입되는 것으로 우선순위가 고정되어, 상단 큐에 모든 작업이 끝나야 다음 우선순위 큐의 작업이 시작된다. 이 방식은 선점형 방식으로
다단계 피드백 큐 스케줄링(MLQ, Multi-Level Feedback Queue)
MLQ의 문제를 보완한 방식으로 CPU를 사용한 후에는 우선순위를 낮추어 아사현상을 해결한다.(그러나 커널 프로세스가 일반 프로세스 큐에 삽입되지는 않는다) 또한 우선순위가 낮으면 타임 슬라이스를 크게하여 우선순위가 낮은 프로세스에게 실행기뢰를 확대한다. 하지만
인터럽트 처리
- 폴링 : 입출력이 요청되면 운영체제가 주기적으로 입출력 장치를 직접 확인해서 처리하는 방식
- 인터럽트 :
동기적 인터럽트
란 프로세스가 실행 중인 명령어로 인해 발생하는 인터럽트로 사용자 인터럽트라고도 한다. 예를들어 프로그램 상의 문제로 다른 사용자의메모리에 접근하거나
비동기적 인터럽트
란 실행중인 명령어와 무관하게 발생하는 인터럽트이다.
이 인터럽트의 처리과정은 단순하다.
- 인터럽트가 발생하면 실행중인 프로세스는 일시 정지 상태가 되며 재시작을 위해 현재 프로세스 관련 정보를 임시로 저장한다.
- 인터럽트 컨트롤러가 실행되어 인터럽트 처리 순서를 결정한다.
프로세스 동기화
프로세스 간 통신
프로세스 혹은 스레드는 독립적으로 실행된다. 스레드는 하나의 프로세스 내에서 자원을 공유하는 실행단위이고, IPC(Inter Process Communication)
은 운영체제에 의해 프로세스 간에 데이터를 주고 받는 프로세스 간 통신이다. IPC에는 다음과 같은 종류가 았다.
- 공유메모리나 공유 파일을 이용한 통신 : 일정한 메모리 여역이나 파일을 공유하는 원시적인 방법
- 파이프를 이용한 통신 : 파이프는 운영체제가 제공하는 통신기법으로 보통 fork()로 부모-자식 간 통신에 사용된다
- 소켓을 이용한 통신 :
프로세스 간 통신을 분류
- 양방향 통신(duplex communication) : 데이터를 양쪽으로 전송 가능, 소켓을 이용
- 반양방향 통신(hlafduplex communication) : 데이터를 양쪽으로 전송 가능하나 동시 전송은 불가 ex)무전기
- 단방향 통신(simplex communication) : 한쪽으로만 데이터 전송 가능, 공유 메모리나 공유 파일, 파이프를 이용
통신 구현방식에 따른 분류
- 대기가 있는 통신(동기화 통신) : 데이터가 도착할때까지 자동으로 대기 상태 ex) 전화
- 대기가 없는 통신(비동기화 통신) : 바쁜대기를 사용해 데이터가 도착했는지 여부 확인 ex) 전보
프로세스간 통신의 종류
- 파일을 이용한 통신 : 파일열기(open() 함수로 파일이 있는지, 쓰기 권한인지, 파일 기술자 fd를 반환) - 파일 읽기 쓰기(write(fd,~),read(fd,~)) - 파일 닫기(close(fd))의 과정
- 파이프를 이용한 통신 : 파일 입출력 처럼 open(), close(fd)로 통신, 단방향 통신이지만 파이프 2개 사용시 양방향 통신 가능
- 이름 없는 파이프 : 부모와 자식 또는 같은 부모를 가진 자식 프로세스와 같이 서로 관련이 있는 프로세스 간 통신
- 이름 있는 파이프 : FIFO를 이용
- 소켓을 이용한 통신 : 네트워킹으로 서로 다른 컴퓨터의 프로세스끼리 통신, 컴퓨터의 위치를 파악하는데 IP를 이용, 다른 컴퓨터의 프로세스를 구분하기 위해 포트번호인 TCP 이용, 서버에서 돌아가는 프로세스인 데몬도 포트번호 필요
공유 자원과 임계구역
공유자원(shared resource)
이란 여러 프로세스가 공동으로 이용하는 변수,메모리,파일 등 이다. 경쟁조건(race condition)
이란 2개 이상의 프로세스가 공유 자원을 병행적으로 읽거나 쓰는 상황이다. 경쟁 조건이 발생하면 공유자원 접근 순서에 따라 결과가 달라질 수 있다. 임계구역(critical section)
이란 공유자원 접근 순서에 따라 실행결과가 달라지는 프로그램 영역이다. 만약 프로세스가 읽기만 한다면 공유자원이라해도 임계구역이 아니다. 만약 공유자원을 임계구역으로 지정하면 임계구역에서 프로세스의 작업을 마쳐야지 다른 프로세스가 작업을 할 수 있기 때문에 문제가 발생하지 않는다.
임계구역과 관련된 대표적인 문제를 생산자-소비자 문제
라고 한다. 생산자와 소비자 프로세스는 서로 독립적으로 작동하며, 버퍼에 생산자는 물건을 넣고, 소비자는 물건을 가져간다. 이때 버퍼에 담긴 물건의 개수를 저장하는 전역 변수 sum이 있다. 생산자가 물건을 담았고 sum을 바꾸기 전에 소비자가 물건을 가져가고 sum을 수정하면 문제가 발생한다.
임계구역 문제를 위해 3가지 해결책이 있다.
상호배제(mutual exclusion)
: 임계구역에는 하나의 프로세스만 들어갈 수 있다.한정대기(bounding waiting)
: 어떤 프로세스가 임계구역을 무한정 사용해 다른 프로세스가 무한대기 하면 안된다.진행의 융통성(progress flexibility)
: 한 프로세스가 다른 프로세스의 진행을 방해해서는 안된다.
임계구역 문제 해결 방법
임계구역 문제를 해결하기 위해 기본적으로 ‘잠금’을 사용할 수 있다. 잠금을 공유변수로 두고 작업을 시작하기전 잠금을 true로 하고 작업이 끝나면 잠금을 false로 한다. 다른 프로세스가 접근을 하면 잠금이 false가 될떄까지 while문이 무한정 돌아간다. 이 방법의 단점은 while문 직후에 문맥교환이 일어나면 잠금이 풀리고, 다른 프로세스는 잠금이 풀리기를 기다리면서 바쁜대기를 해야한다는 것이다.
이 한정대기 문제를 해결하기 위해 잠금 공유변수를 2개를 사용하고 while문 이전에 상대방에게 잠금을 거는 방식이 있다. 하지만 이 방식도 문제가 있는데 상대방에게 잠금을 걸고 문맥교환이 일어나면 무한 대기를 한다는 것이다. 이러한 상황을 교착상태라고 한다.
피터슨 알고리즘은 turn이라는 공유번수를 사용한다. 이 방식은 상대에게 잠금을 걸고 turn의 값을 변경한다. 만약 문맥교환이 일어나도 while문 조건에 turn이 and로 걸려있기 때문에
피터슨 알고리즘과 데커 알고리즘은 임계구역 해결의 세가지 조건을 모두 만족하지만 복잡하다.
void process1(){
lock1=true;
while(lock2==2){
lock1=false;
while(tuen==2);
lock1=true;
}
}
세마포어 알고리즘은 위에 알고리즘보다 간단하고 사용하기 쉽다. 하지만 사용자의 실수로 아래와 같이
Semaphore(n);//n은 공유 자원 개수
P();//잠금을 수행
//(임계구역)
V();//잠금 해제와 동기화(대기중인 프로세슷에게 wake_up()신호를 보냄)
파일, 파이프, 소켓 프로그래밍
순차파일
은 데이터가 한줄로 저장되는 형태이다. 파일은 open(), read(), write(), close() 연산을 사용하는데 open을 통해 파일 기술자 fd를 얻고 fd를 통해 파일을 읽고 쓰고 닫는다. 이 파일을 이용해 통신을 할 수 있다. fork()를 하기전에 open()을 하여
파이프를 이용한 통신은
교착상태(deadlock)
교착상태(deadlock)
란 다른 작업이 끝나기만을 기다리며 작업을 더이상 진행하지 못하는 상태
아사현상과 deadlock의 차이는 아사현상은 알고리즘의 문제로 발생하는 반면, deadlock은 자연스럽게 발생하는 현상이다.
교착상태 방생 원인은 다음과 같다.
- 다른 프로세스와 공유할 수 없는 시스템 자원을 사용
- 임계구역에서 잠금을 사용할때
- 데이터베이스에서 데이터 일관성이 깨진 경우
자원할당 그래프
는 프로세스가 사용중인 자원, 기다리는 자원을 방향성 있는 그래프로 표현한 것이다. 프로세스는 원으로, 자원은 사각형으로, 자원을 사용중인 경우 자원에서 프로세스로 화살표를, 자원을 기다리른 경우 프로세스에서 자원으로 화살표(점선)로 그린다.
여러 프로세스가 동시에 사용하는 자원을 다중자원이라하며, 한 자원에서 여러 프로세스에 화살표로 가리킨다.
교착상태는 식사하는 철학자 문제
로 설명할 수 있다. 4개의 철학자(프로세스)가 둥근 식탁에 앉아 있고, 그위에 4개의 포크(자원)이 있다. 이때 모든 철학자가 동시에 자신의 왼쪽 포크를 잡고, 오른쪽 포크를 잡아야 식사를 할 수 있다. 포크는 4개 밖에 없기 때문에 각 철학자는 왼쪽 포크를 잡고 오른쪽 포크를 잡지 못해 굶어 죽는다
교착상태가 발생하는 필요조건은 다음과 같다. 4가지를 모두 만족해야 교착상태가 발생한다.
- 상호배제 : 철학자는 포크를 공유할 수 없음
- 비선점 : 다른 철학자의 포크를 뺏을 수 없음
- 점유와 대기 : 철학자는 포크를 잡고 다른 포크를 기다리는 상태
- 원형대기 : 포크를 잡고 있고, 포크를 기다리는 철학자는 식탁에 원으로 앉아 있어야함
[교착상태 해결]
교착상태를 해결하는 방법은 4가지가 있다.
예방
: 교착상태의 4가지 조건을 사전에 예방하는 것이다. 실효성이 떨어진다.- 상호배제 예방 : 모든 자원을 공유할 수 있게한다. 하지만 임계구역을 보호하지 못한다.
- 비선점 예방 : 모든 자원을 뺏을 수 있게한다. 하지만 아사현상을 일으킬 수 있다.
- 점유와 대기 예방 : 필요한 자원을 모두 할당받을 수 없으면, 아예 할당을 받지 않는 것이다. 이 방법은 프로세스가 필요한 자원을 파악하기 어렵고, 자원의 활용성이 떨어지며, 많은 자원이 필요한 프로세스는 아사현상이 발생할 수 있으며, 일괄 작업 방식으로 처리된다는 단점이 있다.
- 원형 대기 예방 : 자원에 번호를 붙여 점유 중인 자원보다 번호가 큰 자원만 할당받을 수 있게한다. 하지만 자원의 번호에 따라 사용하지 못하는 자원이 생겨 유연성이 떨어지며, 자원 번호를 어떻게 부여할지 결정하기 어렵다는 문제가 있다.
회피
: 안정상태이면 자원을 할당하고 불안정상태이면 할당을 하지 않는다. 실효성이 떨어진다.은행원 알고리즘
: 자원 할당을 은행의 대출에 대응하는 방법이다. 이 알고리즘에서 사용하는 변수는 Total(전체자원), Available(가용자원), Max(최대자원), Allocation(할당자원), Expect(기대자원=최대자원-할당자원)이고 각 프로세스는 운영체제에게 Max값을 알려준다. 안정상태는 기대자원≤가용자원인 경우가 한 번 이상인 경우이다. 그러나 프로세스가 자원의 개수를 파악해야하고, 시스템의 전체 자원 수가 고정적이지 않으며, 자원이 낭비된다는 단점으로 사용되지 않는다.
검출 & 회복
: 자원할당 그래프를 모니터링하면서 교착상태가 발생하면 회복한다. 현실적인 해결책이다. 회복 단계에서는 강제 종료된 프로세스가 실행되기 전에 가장 최근의 검사 시점으로 시스템을 복구하는 일도 해야한다. 이 작업은 작업량이 상당하다.- 검출(타임아웃) : 작업이 일정시간동안 진행되지 않으면 교착상태로 처리한다. 가벼운 교착 상태 검출이라고도 한다. 단점은 엉뚱한 프로세스가 강제 종료될 수 있다는 점, 모든 시스템에 적용할 수 없다는 점(e.g. 네트워크로 연결된 분산 데이터베이스, 안정성이 요구되는 시스템)이 있다.
- 검출(자원할당그래프) : 자원할당 그래프를 이용해 사이클을 존재하는지 확인하는 방식이다. 문제는 사이클이 있다해도 다중자원을 사용하는 경우 교착상태가 아닐 수 있으며, 사이클을 검사하는 과정에서 오버헤드가 발생할 수 있다.
- 회복(모든 자원 동시 종료) : 교착상태를 일으킨 모든 자원을 강제 종료한다. 그후 프로세스를 순차적으로 실행한다.
- 회복(하나씩 순서대로 종료) : 다음 기준으로 순서대로 종료(1.우선순위 낮음, 2.작업시간 짧음, 3.자원을 많이 사용)
물리 메모리 관리
메모리 관리 개요
- 메모리 관리 복잡성 : 폰노이만 구조에서 시분할 시스템은 메모리에 여러 프로그램이 동시에 실행
- 메모리 관리 이중성 : 프로세스는 메모리 독차지, 운영체제는 메모리 효율적 관리
컴파일 : 소스코드 >(컴파일러)> 목적코드 >(링커)> 실행
메인 메모리 = 물리 메모리
메모리는 메모리 관리자가 관리
메모리가 꽉찼는데 프로세스가 생성되야 할 경우 메모리에 있는 프로세스를 swap영역으로 보내고(보류상태) 메모리에 적재.
fetch(가져오기)
: 실행할 프로세스와 데이터를 메모리로 가져오는 작업
placement(배치)
: 가져온 프로세스와 데이터를 메모리에 어떤 위치에 놓을지 결정하는 작업
replacement(재배치)
: 메모리가 꽉찼으면 메모리에 프로세스를 스왑영역에 옮김
메모리 주소
물리 주소 논리 주소
메모리 오버레이
프로그램이 남은 메모리 공간보다 클때 프로그램을 모듈로 나누어 메모리에 적재 나머지 부분은 swap영역에 적재
swap 영역
: 메모리가 모자라서 프로세스를 저장하는 하드웨어에 영역. 하드웨어에 있지만 메모리 관리자가 관리하고, 실제 메모리 크기+swap 영역을 메모리의 크기로 인식. swap in(스왑영역으로 들어옴), swap out( 스왑영역에서 메모리로)
멀티 프로그래밍 환경에서 메모리 할당 방법
가변 분할 방식(segmentation 메모리 관리 기법)
프로세스 크기에 따라 메모리 나누는 것.
메모리 영역이 각각 다름.
연속 메모리 할당
-프로세스를 하나의 연속된 주소로.
외부단편화
- 프로세스가 완료되면 빈공간이 생기는데(단편화)
외부단편화를 메모리 배치 방식(선처리)
이나 조각 모음(후처리)
으로 해결
메모리 관리 복잡 / 외부단편화가 발생하면 프로세스들을 모두 옮겨 빈공간을 채워야함
메모리 배치 방식
- 최초 배치(first fit) : 첫번째로 발견한 공간에 배치 / 성능 굿
- 최적 배치(best fit) : 가장 작은 공간에 배치 / 공간이
- 최악 배치(worst fit) : 가장 큰 공간에 배치 / 공간이 충분히 크다면 오히려 좋다
조각모음 : 메모리 중간에 빈 공간이 생기면 프로세스를 붙여서 연속적으로 만드는 작업 / 조각모음 중간에 프로세스 동작 못함,
고정 분할 방식(paging 메모리 관리 기번)
프로세스를 고정된 크기(page)로 나누어 메모리에 적재.
현대 메모리 관리 기법
프로세스가 일정 크기보다 작다면 빈공간 생김
비연속 메모리 할당
메모리 관리 수월, 쓸모없는 빈공간으로 메모리 낭비
내부단편화 : 조각 모음에 빈공간이 남는것(고정 크기보다 나누어진 프로세스 크기가 작을때)
메모리 관리가 편함 /
프로세스 배치
버디 시스템
가변 분할 방식과 고정 분할 방식의 중간 개념. 둘다 같이 사용 가변 분할 방식의 단점(외부단편화)을 완화 프로세스를 고정된 크기로 나누어 배치하는게 아니라 메모리 구역을 절반으로 계속 잘라 프로세스가 배치될 수 있는 가장 작은 메모리 영역에 배치
비슷한 크기의 덩어리가 모여있어 서로 통합하기 쉬움(외부단편화 완화) 하지만 매번 프로세스 크기만큼 메모리를 나누고, 작은 조각을 통합하여야 되기 때문에
? 버디시스템에서 메모리 오버레이 사용불가?
현재에는 고정 분할 방식이 더 쓰임
분할 컴파일
- 다중 소스코드 : 여어개 소스코드 하나의 실행파일로
- 분할 컴파일 : 여러개 소스코드를 각각 컴파일하여 하나의 실행파일로
- 심벌테이블 : 변수의 이름 / 타입 / 범위(메인함수인지) / 주소
가상 메모리 기초
가상 메모리 개요
가상메모리
: 실제 물리 메모리 크기에 의존하지 않고 유연하게 작업 가능하게 하는 목적, 물리메모리+스왑영역
프로그래머가 응용프로그램을 개발하는데 동작환경의 메모리 크기를 신경쓰지 않고 개발가능 가상 주소 - 0번지 부터 시작하는 연속된 메모리공간(논리 주소는 물리메모리 주소 공간에 비례한다는 차이점)
프로세스가 바라보는 메모리 영역 - 메모리 관리자가 보는 메모리 영역 -
동적주소변환(DAT)
: 가상 주소 -> 물리 주소 변환하는 작업
매핑 테이블 : 가상 주소와 물리 주소()를 일대일 매핑한 테이블 페이지 매핑 테이블 / 페이지 테이블 : 페이징 기번 사용 세그멘테이션 매핑 테이블 / 세그멘테이션 테이블 : 세그멘테이션 기법 사용
지역성
: 기억장치에 접근하는 패턴이 메모리의 특정 영역에 집중된다는 성질
공간의 지역성 : 현재 위치에서 가까운 위치의 데이터 접근 가능성 높음
시간의 지역성 : 가장 최근 접근한 데이터가 사용률 높음
순차적 지역성 : 작업이 순서대로 진행됨
지역성을 캐시와 페이지 교체 알고리즘에 응용
페이징 기법
고정 분할 방식으로 가상 메모리 관리 기법 가상 주소에 분할된 각 영역을 페이지라하고 번호를 매긺 물리 주소에서 분할된 각 영역을 프레임이라하고 번호를 매긺 페이지 프레임 크기 같음
DAT(동적주소변환)과정 - VA=< P,D> -> 페이지 테이블 -> PA=< F,D>
VA =< P,D> 에서 P는 페이지 번호, D는 페이지 내부 위치(0<=D<페이지 크기) F는 프레임 번호
프로세스 마다 페이지 테이블을 가짐. 페이지 테이블 크기를 적정하게 유지하는게 페이지 테이블 관리의 핵심
PCB 경계 레지스터 한계 레지스터에 가상 주소를 가지는가?
페이징 관리 기법
각 프로세스의 페이지 테이블은 페이지 테이블 기준 레지스터에 보관(운영체제 영역)
프로세스를 복사하면(fork)
가상주소 물리주소로 변환은 MMU관리 페이지 테이블 접근 > 사용사 물리주소접근
하지만 물리주소를 두번 접근 하는것은 비효율적 > 변환 색인 버퍼TLB(캐시와 비슷, CPU에 테이블을 가져옴)로 해결 TLB 히트, TLB 미스
역페이지 테이블 프레임을 페이지로 프로세스 수와 상관없이 테이블이 하나만 존재, 테이블 크기가 작은 것이 장점 <프레임번호, 프로세스 아이디, 페이지 번호> 주소 변환시 프로세스가 물리 메모리에 있는지 확인 없으면 스왑영역에서
다단계 페이지 테이블
운영체제 비트수가 크면 주소 공간이 기하급수적으로 커짐 > 이걸해결 페이지 테이블을 여러 무끙ㅁ으로
2단계 페이지 테이블 VA =< P1,P2,D> (디렉토리 테이블 위치정보, 묶음에서 위치정보, D는 그대로)
세그멘테이션 기법
세그멘테이션 테이블 물리 메모리 시작주소나나냄, size대신 limit가 쓰임 장점은 페이지테이블이 작고 단순,but 외부단편화 관리 복잡
세그멘테이션 테이블 (limit, address) (스왑영역이면 address가 I(invalid))
VA=< S, D> S: 세그멘테이션 번호 D: 시작주소에서 거리
리미트보다 디가 크면 트랩, 의도치않은 오류는 ㄴ
캐시 매핑
캐시 직접 매핑
메모리는 N개의 페이지, 캐시는 M개의 페이지(N>M)
캐시 연관 매핑
메모리가 캐시의 어느 위친든 올라감
캐시 집합 연관 매핑
다중메모리
요구 페이징
사용자가 요구 > 페이지를 메모리로(현대 방삭) 장점은 메모리 절약 효율적관리 미리가져오기(요구 페이징과 반대)
페이지 부재 - 페이지에 없음
페이지 교체 - 페이지 부재가 발생하면 스왑에 페이지를 메모리로 올리고 페이지 테이블 갱신
페이지 교체 알고리즘 - 어떤 페이지를 스왑으로 보낼것인가
대상 페이지(victim page) - 스왑에 올라가는(스왑아웃) 페이지
페이지 교체 알고리즘
대상 페이지 결정
사용할 가능성이 적은 페이지 선택
간단한 알고리즘 - 무작위, FIFO 이론적 알고리즘 - 최적(앞으로 사용할 페이지 분석 / 이상적이지만 구현 불가능) 최적 근접 알고리즘 - LRU(시간적으로 멀리 떨어진), LFU(사용빈도가 적은), NUR(최근 사용한 적 없는), FIFO변형
LUR과 LFR은 성능은 좋지만 추가 오버헤드가 있음 NUR은 페이지당 2비트(참조 비트, 변경 비트)만 사용 참조비트 페이지에 접근하면 1, 변경비트 페이지 변경되면 1, 둘다 11이면 00으로 초기화
성능 평가 기준 - 같은 메모리 접근 패턴을 사용하여 페이지 부재 횟수, 페이지 성공 횟수 측정
스레싱과 프레임 할당
스레싱 : 하드디스크 입출력이 많아져 작업이 멈춘것 같은 상태 스레싱 발생 지점 : CUP작업시간 < 페이지 교체 시간 물리 메모리 크기 늘리면 스싱 발생 지점 늦쳐짐
프로세스당 프레임 조금 할당 > 페이지 부재 빈번 > 스레싱 발생 프로세스당 프레임 많이 할당 > 메모리 낭비
따라서 프레임을 할당하는 방식을 정적할당과 동적할당으로 나뉨 동등 할당 - 프로세스에게 할당하는 프레임 수를 같게 - 프로세스 크면 스레싱, 작으면 메모리 낭비 비례 할당 - 프로세스 크기에 비례해서 할당할 프레임 개수를 결정 but 실행중 변경 불가 작업집합 모델 - 페이지 부재 빈도 - 페이지 부재 횟수 기록 상한선 넘으면 페이지 할당 하한선 아래면 페이지 회수
전역 교체 지역 교체
입출력 시스템 & 저장장치
입출력 시스템
주변장치
- 저속주변장치 - 키보드 마우스 등 ; 사용자에게 입력
- 고속주변장치 - 그래픽카드, 하드디스크 등
병목현상 방지를 위해 주변장치와 연결된 여러개의 버스를 묶어 사용
- 채널 공유 : 느림
- 채널 분리 : 입출력이 비슷한것끼리
초기 - 버스 하나, 폴링방식 현재 - 메인버스, 입출력버스 두개의 버스로 분리, 두 버스 사이에는 입출력 제어기 현재2 - 입출력버스를 고속 -와 저속 -로 분리, 두 버스 사이에는 채널 선택기 그래픽 카드는 메인버스에 바로 연결(그래픽 버스)
직접 메모리 접근(DMA)
: 입출력 제어기가 CPU 허락받지 않고 메모리 접근할 수 있는 권한
DMA 제어기가 관리
과거에는 메모리와 분리된 입출력메모리를 사용
현재에는 메모리 맵드 IO
인터럽트 각 장치는 IRQ 고유번호를 가짐 외부 인터럽트 : 입출력장치 전원이상 등 하드웨어 이상 내부 인터럽트 : 프로세스에서 발생하는 신호
인터럽트 벡터 : 인터럽트 발생여부(0 or 1), 인터럽트 핸들러 배열로 모아놓은것
이중버퍼 : 단방향 버퍼 두개로 양방향 데이터 이동 속도 빠름
저장장치
하드디스크
- 플래터 : 원반 한장, 가지를 N-0과 S-1로 저장, 개수는 보통 2장 이상, 항상 일정 속도
- 섹터 : 하드디스크 가장 작은 저장단위
- 블럭 : 하드디스크-컴퓨터에 데이터를 전송하는데 논리적인 가장 작은 단위, 여러개의 섹터로 구성, 윈도우는 클러스터
- 가장 작은 저장단위 - 하드디스크는 섹터, 운영체제는 블럭
- 트랙 : 플래터에서 동그라미 선, 섹터의 집합
- 실린더 : 야러개의 플래터에서 같은 트랙의 집합
- 헤드 :
SSD
- 하드디스크의 느린 속도를 대체
- 플래시 메모리로 구성
- 발열 작고, 속도 빠르고, 저력량 낮고, 입출력 속도 빠르고 but 가격 비쌈
- 단편화가 데이터 접근 속도에 영향을 미치지 않아 조각모음 필요없음
CD
- 하나의 원반, 트랙과 섹터 존재, 헤드가 데이터를 읽음
하드디스크 vs CD
- 하드디스크 - 각속도 일정 방식의 회전 / 조용 but 바깥쪽 공간 낭비(모든 트랙 섹터 수 동일)
- CD - 선속도 일정 방식의 회전 / 공간 낭비 X but 제어 복잡 소음
하드 데이터 전송시간
- 하드 - 1.탐색시간(트랙 탐색) + 2.회전지연시간(섹터 기다림) + 3.전송시간
디스크 스케줄링
트랙 이동을 최소화하여 탐색 시간을 줄이는 것이 목적
알고리즘 성능 테스트할 트랙번호 - 15 8 17 11 3 23 19 14 20
트랙은 0~24, 총 25개
FCFS : 요청 들어온 순서ㄷ로 서비스
- 처음 위치는 15, 이제 다음 트랙 위치 별로 플마해서 이동거리 구함
SSTF : 현재 헤드가 있는 위치에서 가장 가까운 트랙ㅂ터 서비스
- 아사현상 발생
- 이동 거리 = (MAX-현재 헤드위치) + (MAX-MIN)
블록 SSTF : 몇개의 트랙을 블럭으로 묶어 큐로 넣음, 블록안에서 SSTF방식, 블록 다끝나면 다음 블록
- 에이징을 사용
- 성능은 FCFS 만큼 안좋음
SCAN 디스크 : 계속 한방향으로 이동하여 트랙읽음, 끝이면 방향 바꿔서
- 아사현상 발생 - 같은 트랙읽는 요청 발생
- 끝에 트랙은 가운데 보다 서비스 회수가 적음
C-SCAN 디스크 : SCAN에서 다른 방향으로 이동할때는 서비스 하지 않음
- 작업없이 헤드를 이용하는 것은 비효율적
LOOK 디스크 스케줄링
- 더이상 서비스할 트랙 없으면 헤드가 끝까지 가지않고 중간에 방향바꿈(반대방향은 서비스X)
STLF 디스크 : 헤드를 곶어
RAID
자동으로 백업, 장애발생하면 복구
- 미러링 : 백업 디스크에 복사본
- 스트라이핑 : 여러 디스크에 데이터를 나누어 동시에 저장(병렬적으로), 속도 빠름
레이드 뒤에 넘버링은 기능, 여러 넘버링의 RAID를 합쳐서 사용
- RAID 0 : 스트라이핑(디스크 개수만큼 배로 빠름), 장애발생 대책없음, 1,5,6과 같이 사용
- RAID 1 : 미러링, 두번 저장하기 때문에 속도 느려짐(절반)
- RAID 2 : 오류교정코드(ECC)를 따로관리(디스크개수-1 개 필요), 오류발생하면 이 코드로 디스크 복구, 오류 교정 코드계산 하는데 오래걸림(그래서 안씀)
- RAID 3 : N-way 패리티 비트로 섹터 단위로 데이터 복원, 디스크 양적지만 계산량 많음
- RAID 4 : 대이터를 하나의 블ㄹ록 단위로 저장, 패리티 비트를 블럭 단위로
- RAID 5 : 패리티 비트를 여러 디스크에 분산, 병목현상 완화
- RAID 6 : 패리티 비트를 2개로
- RAID 01 / 10 : 레이드 0으로 묶고 1로 묶음 / =1=0= , 10은 문제 발생시 일부 디스크만 중단, 01은 모든 디스크 중단
- RAID 50 / 60 :
+하드웨어
메인보드 포트
- 직렬 포트
- 병렬 포트
- usb 포트
파일 시스템
- 파일 관리자는 파일 테이블로 파일 관리
- 파일 디스크립터 - 파일 접근 권한
파일 시스템 기능
- 파일 및 디렉터리 구성 & 관리
- 접근 방법 제공
- 접근 권한 제공
- 무결성 보장
- 백업과 복구
- 암호화
파일 테이블
- 블록 : 저장장치에서 사용하는 가장 작은 단위, 한블록에 하나 주소, 파일 크면 큰 블록
- 2차원 (가로-블록번호/세로-블록*블)
파일 이름 형식
-
윈도우 금지 - \/:*?”<> - 유닉스 금지 - 특수문자
- 윈도우는 대소문자 구분 X, 유닉스는 대소문자 구분 O
파일 연결 프로그램-데이터 파일을 실행시키는 프로그램
파일 작업
- 파일 자체 변경 - open, close, create, remove, copy, rename, list, search
- 파일 내용 변경 -
파일 헤더
- 파일 맨 앞에 위치
- 내용 파일 버전 번호, 크기, 특수 정보
파티션
- 저장장치를 논리적으로 분할
포맷
- 빠른 포맷 - 파일 테이블만 초기화
- 느린 포맷 - 파일 테이블과 블록의 모든 데이터 0으로 초기화
- 포맷 할때 블록의 크기 지정가능
조각 모음
- 조각화된 빈공간을 붙여 없앰
- usb나 ssd는 조각 모음 안해도됨
순차 파일 구조
- 모든 데이터 순서대로, 낭비 없음, 구조 단순, 읽기 저장 빠름
- 그러나 파일에 삽입 삭제 오래걸림, 직접 접근이 어려워 데이터 검색 적합 안
인덱스 파일구조
직접 팡리 구조
- 해시 함수로 데이터 값에 따른 주소를 할당
- 상수 시간복잡도의 접근 시간
- 충돌 안나는 해시 함수 어려움, 저장 공간 낭비