운영체제(OS)
등장배경
처음엔 하드웨어의 종류가 적어 통제가 가능했으나 점차 하드웨어의 종류가 많아지고 다양한 용도로 사용되면서, 개발자가 모든 하드웨어의 구조와 회로를 배우는 것이 불가능하게 되었다. 프로그램이 하드웨어 위에서 잘 실행될 수 있도록 도와주기 위해서 등장한 것이 운영체제.
: 하드웨어를 포함한 리소스를 제어하고 프로그램을 실행해주는 시스템 소프트웨어
- 시스템 리소스: 시스템 자원
- 컴퓨터에서의 자원: 어떤 목적에 이용할 수 있는 하드웨어를 포함한 모든 것
- ‘리소스’의 99% → 메모리를 의미
- 각 응용프로그램마다 할당된 리소스가 존재
- 응용프로그램은 다른 응용프로그램의 리소스를 강제로 사용할 수 없음
⇒ 응용프로그램이 실행되기 위해 누군가 리소스를 정해주고 각 프로그램이 다른 프로그램의 리소스를 강제로 사용할 수 없도록 누군가 막고 있음 → “운영체제”
운영체제의 기능
1. 프로세스 관리
- 리소스 관리: 프로세스에 필요한 리소스 할당(주거나 사용 안하면 뺏음)
- 프로세스 상태관리: 각 프로세스의 상태를 관리
- 멀티 프로세싱: 동시에 여러 프로세스를 실행
2. 메모리 관리
- 메모리에 프로그램을 올리고 프로세스에게 필요한 메모리를 할당
- 가상 메모리: 실제 주소가 아닌 가상의 주소로, 실제 메모리가 적어도 프로세스를 실행할 수 있도록 도와줌
- ex. 안심번호. 택배기사님이 실제 번호가 아닌 안심번호를 사용한다면 개인 정보도 보호되고 안심번호를 연속되게 설정함으로써 여러 사람에게 문자를 보낼 때 더욱 빠르게 전송 가능
- 정보보호: 프로세스가 실제 주소를 모르기에 메모리 주소를 악용한 침범이 불가능함
- 연속주소 제공: 프로세스가 보는 주소는 연속된 주소로 처리할 수 있어서 효율적인 처리 가능
3. 파일 시스템 관리
- 어떤 방식을 사용하던지 프로그램에서 고민하지 않고 읽고 쓰게 해주는 기능
4. 네트워크 관리
- 프로토콜을 지원하여 통신이 가능하도록 함
- 프로토콜: 네트워크 상의 컴퓨터끼리 통신하는 규칙
- 포트를 관리하여 이미 사용중인 포트는 사용할 수 없도록 제어
✅ 프로세스
- 프로세스: 실행 중인 프로그램
- 프로그램: 특정 작업을 수행하는 명령어들의 모음 → 프로그램이 실행되는 프로세스
- 스레드: 프로세스 안에서 실행되는 흐름 단위 → 프로세스에는 하나 이상의 스레드가 존재
- 프로세스 vs 스레드
- 프로세스는 독립적인 메모리를 할당 받음. 스레드는 프로세스 속에 있는 것으로 프로세스가 받은 메모리를 공유
- 프로세스의 구조
- 스택
- 임시 데이터(함수 호출, 로컬 변수 등)이 저장되는 영역
- 함수의 호출과 함께 할당되고, 호출이 완료되면 소멸
- 프로세스별로 크기 제한
- 데이터 저장하는 선형 자료 구조. LIFO 방식
- 힙
- 코드에서 동적으로 생성되는 데이터가 저장되는 영역
- 동적 메모리 할당을 위해 사용되는 메모리 영역
- 사용자가 직접 관리할 수 있는 메모리 영역
- 상대적으로 느리며 관리를 잘못할 경우 메모리 누수 발생
- 메모리 누수: 할당해놓고는 사용하지 않은 채로 냅두는 것.
- 데이터 → 크기 고정
- 전역 변수, 정적변수, 배열, 구조체 등이 저장되는 영역
- 프로그램의 시작과 함께 할당되고 프로그램 종료되면 소멸
- 프로그램이 시작되는 시점부터 종료 시점까지 추가되거나 사라지지 않는 공간
- 코드 → 크기 고정
- CPU가 볼 수 있는 언어로 기록된 코드들로, 실행할 명령어를 저장하는 영역
- 실행되는 시점에는 읽기 전용 영역이 되어서 수정이 불가능함
- 스택
※ 정적할당: 실행 중에 변하지 않는다. 실행 전에 미리 메모리를 할당. 할당받을 크기가 미리 정해져 있음.→ 정적할당이 동적할당보다 속도가 빠름
※ 동적할당: 실행 중에 변한다. 실행 도중에 메모리를 할당. 실행 도중에 할당 받을 크기가 변할 수 있음.
- 프로세스의 상태
- 생성(New) → “번호표 들고 식당밖에서 대기”
- 준비 상태로 메모리에 올라가지 않은 상태
- 대부분 바로 준비상태로 승인되지만, 리소스가 부족하면 오래 대기할 수 있음.
- 준비(Ready) → “식당에 들어가서 앉아있는 상태”
- 프로세스가 CPU를 사용하고 있지 않지만 언제든 실행될 수 있도록 대기하는 상태
- OS는 우선순위가 높은 순서대로 CPU 할당해서 실행 상태로 전이
- 실행(Running) → “나온 요리 먹는 단계”
- CPU가 할당되어 프로세스의 명령어들을 처리해주는 단계
- 동시에 다른 프로세스들을 처리하기 위해 일정시간 이후 다시 준비 상태로 전이
- 기본적으로 CPU는 한 번에 하나만 실헹할 수 있지만 최근엔 멀티코어라는 기술로 여러 프로세스를 실행시키기도 하지만 각각의 코어도 한 번에 하나의 프로세스를 처리.
- 대기(Blocked) → “화장실 다녀오는 상태”
- 프로세스가 특정 자원이나 이벤트를 기다리는 상태
- 입출력 완료 등 특정 이벤트를 기다리는 상태
- 이벤트가 완료되면 ready 상태로 옮겨와서 계속 실행
- 종료(Terminated) → “일어나서 나갈 준비”
- 모든 명령어가 완료된 상태
- 부모 프로세스가 상태 확인을 위해 바로 삭제되지 않고 대기
- 종료가 되었지만 삭제되지 않은 프로세스로 좀비 프로세스라고 부름
- 이 상태 끝나면 프로세스가 메모리에서 삭제
- 생성(New) → “번호표 들고 식당밖에서 대기”
- 멀티 프로세싱
- 멀티스레드
- “한 집안에서 동시에 여러 집안일 처리”
- 한 프로세스 내에서 자원을 공유하면서 여러 작업 처리 → 하나의 변수를 가지고 각자 작업이 가능
- 새로 프로세스를 생성하고 리소스를 할당받는 과정이 없어서 더 빠르게 처리 가능
- 하나의 스레드에 문제가 생기면 프로세스 전체가 종료될 수 있음
- 멀티 프로세싱
- “여러 집에서 동시에 여러가지 집안일 하기”
- 프로세스간 통신(IPC)
- 다른 집과 접시 효율적으로 주고 받기
- 다른 프로세스의 리소스는 절대 침범하면 안됨
- OS가 허용하는 방법내에서 데이터를 주고 받는 방법
- ex. 메세지 큐, 공유 메모리, 소켓
- 멀티스레드
- 프로세스 스케줄링
- “어떤 손님부터 음식을 해줄 것인가”
- 대기 시간은 가능한 최소화, 가능한 공평하게 프로세스 처리
- 선입선처리
- “먼저 온 손님부터 순서대로”
- 먼저 도착한 프로세스부터 순서대로 처리
- 구현이 간단하고 일괄처리에 효과적
- 빠른 응답 요구하는 환경에서 부적합
- 최단 작업 우선
- “음식을 가장 적게 먹는 손님부터 처리”
- 평균 대기시간을 최소로 만들기 위한 알고리즘
- 작업이 얼마나 걸릴지 예측 어렵
- 오래 걸리는 작업은 매번 양보하면서 평생 처리 완료되지 않을 수 있음
- 라운드 로빈
- “모두 일정한 시간동안 순서대로 요리를 해주는 방식”
- 일정 시간 정해두고 시간 지나면 대기열의 맨 뒤로 보내고 다음 작업 처리
- 응답시간 짧아지는 장점 있어서 실시간 시스템에 유리
- 프로세스 간 전환 많아지는 단점
- 교착상태와 기아상태
- 교착상태
- 프로세스가 서로 상대방의 작업이 끝나기 만을 기다리고 있는 상태
- 결과적으로 아무것도 완료되지 않음
- 발생 조건
- 상호배제: 자원을 동시에 둘 이상 사용 불가능
- 점유대기: 자원을 이미 가진 상태에서 다른 자원 사용하려고 기다림
- 비선점: 다른 프로세스가 자원을 뺏어올 방법 없음
- 순환대기: 각 프로세스가 순환적으로 다음 프로세스가 요구하는 자원 가지고 있음
- 해결
- 은행원 알고리즘: 자원을 할당받기 전 운영체제가 검사하고 할당해줌. 자원 할당해달라고 요청하면 프로세스가 교착상태에 빠질 가능성을 판단해서 없을 경우에만 자원을 할당해줌
- 교착상태 무시: 아무것도 하지 않음. 자주 발생하는 것이 아니라면 무시를 하는 것이 더 좋을 때도 있음.
- 프로세스 종료: 교착상태 발견되면 해당 관련 프로세스를 종료시켜서 해결
- 기아상태
- 프로세스의 우선순위가 낮아서 원하는 자원을 계속 받지 못하는 상태
- 모든 프로세스가 처리될 수 있도록 순서를 정하는 것이 중요
- 우선순위를 수시로 변경하여 계속해서 낮은 우선순위를 가진 프로세스가 없도록 함
- 오래 기다린 프로세스의 우선순위 높이기
- 우선순위가 아닌 순서대로 처리
- 교착상태
✅ 메모리
- 메모리 관리
- 프로그램들이 잘 실행될 수 있도록 메모리를 할당하고 해제하는 작업
- 각 프로그램의 리소스를 보호
- 여러 프로세스가 동시에 실행될 수 있도록 메모리 공간을 제공해야 함
- 용어
- 방 마다 붙어있는 것: 메모리 주소
- 손님에게 방을 주는 것: 메모리 할당
- 손님에게서 방을 다시 가져오는 것: 메모리 해제
- 연속 할당과 불연속 할당
- 연속 할당: 한 손님에게 연속된 방번호로 방을 줌 → 구현 더 쉬움
- 불연속 할당: 방 번호에 상관없이 제공
- 고정 분할방식
- 연속 할당 중 한 방식
- 미리 방을 고정된 길이로 나눠 놓고 손님에게 주는 방식
- 고정된 길이보다 더 많은 방을 원하는 경우. 방은 남는데 방을 줄 수 없는 상황 → 외부 단편화.
- 외부 단편화는 메모리를 크게 낭비
- 고정된 길이보다 더 적은 방을 원하는 경우. 방이 남는 상황 → 내부 단편화
- 내부 단편화는 할당은 했지만 사용하지 않고 남는 공간이 발생하는 경우
- 가변 분할 방식
- 손님마다 다른 방 길이를 받도록 하는 방식
- 내부 단편화 발생 x
- 외부 단편화는 여전히 발생(연속해서 줘야하기 때문에)
- 가상 메모리
- 잘못된 주소에 데이터를 삽입할 수도 있음 → 막기 위해 프로그램 짜는 입장에서 메모리 공간도 신경써야 함 + 사람마다 가진 메모리 공간이 달라서 가지고 있는 메모리가 프로세스보다 작으면 사용 불가능
- 실제 물리적 주소가 아닌 가상의 주소인 논리적 주소를 프로세스가 사용
- 모든 프로세스가 고정된 주소를 가질 수 있도록 함
- 무조건 0번부터 가지게 된다는 의미.
- 실제 물리적 주소는 운영체제만 접근할 수 있어 리소스를 보호
- 보조 기억 장치 일부를 메모리처럼 사용할 수 있도록 함
- 바인딩: 실제주소를 가상의 주소로 매핑하는 것
- 가상 메모리의 원리: 가상 메모리의 페이지와 물리 메모리를 매핑하는 표를 유지
- 페이징
- 물리적 메모리와 가상 주소를 연결하는 단위
- 가상 주소와 물리적 주소를 매핑하는 단위
- 일반적으로 4KB or 8KB의 크기
- 메모리는 페이지 단위를 나누고 사용
- 페이지 테이블: 가상 메모리의 페이지와 물리 메모리를 매핑하는 표
- 스와핑: 안 쓰는 프로세스는 잠시 하드 디스크에 넣어두고 필요할 때 다시 쓰는 것
- 프로세스 스와핑
- 프로세스 단위의 스와핑은 굉장히 비효율적
- 프로세스가 가진 메모리를 통째로 하드 디스크에 넣는다는 것도 비효율적 & 단편화 문제 발생 → 최근에는 사용 x
- 더 많은 프로세스를 실행하기 위해서는 사용하지 않는 프로세스를 하드 디스크에 넣어둘 필요 있음
- 요구 페이징
- 페이지 단위로 스와핑하여 당장 필요한 페이지만 메모리에 남겨두는 방법
- 하드디스크에서 불러오기에 굉장히 느림
- 실제 물리 메모리를 하드 디스크의 캐시로 사용하는 기법
- 캐시
- “손바닥에 메모”
- 빠르게 내용 확인 가능
- 볼펜만 있으면 빠르게 쓰고 지울 수 있음
- 손바닥에 들어갈 정도의 내용만 적을 수 있음
- 데이터나 값을 미리 복사해놓는 임시 장소
- 계산이 오래 걸리는 데이터를 자주 봐야하는 경우 미리 값을 복사해서 시간 절약. 모든 데이터를 넣을 수는 없음
- 페이징 기법의 문제점: 일정한 크기로 자르기 때문에 내부 단편화 발생
- 세그멘테이션
- 같은 크기가 아닌, 논리적으로 같은 역할을 하는 부분끼리 다른 크기로 자르는 방법 ex. 꽃에서 잎은 잎끼리, 줄기는 줄기끼리 등
- 장점
- 중요한 부분과 아닌 부분을 분리해서 저장 → 효율적
- 같은 코드 영역은 하나만 저장하고 같은 곳을 가리키도록 하면 중복된 내용 없앨 수 있음
- 내부 단편화 문제 해결
- 문제점
- 크기가 다르게 자르기 때문에 외부 단편화가 발생할 수 있음
- 일반적으로 외부 단편화가 내부 단편화에 비해 훨씬 큰 공간이 낭비됨
- 페이징 + 세그멘테이션
- 부위별로 먼저 나눈(세그멘테이션 먼저) 다음 각 부위를 일정 크기대로 자름(프로세스를 코드, 데이터, 스택, 힙으로) + 각 파트마다 페이지 테이블을 줘서 자름
- 세그멘트를 페이징 기법으로 나누는 방법
- 세그멘트의 장점 살리면서 외부 단편화 방지
- 테이블 두번 거쳐야 해서 조금 느려질 수 있음
✅ 파일 시스템
- 파일
- 컴퓨터에서 정보를 담는 논리적인 저장 단위
- 파일은 비휘발성 기억장치에 저장
- 메타 데이터(: 파일 관리하기 위한 정보들) 포함
- 디렉토리
- 파일에 대한 여러 정보 갖고 있는 특수한 파일
- 파일을 계층구조로 관리할 수 있음
- 검색, 생성, 삭제 등의 기능 제공
- 파일 시스템
- 파일들을 쉽게 접근할 수 있도록 관리하는 체제
- 디스크, 네트워크, 특수 용도의 파일 시스템으로 나뉨
- 운영 체제는 각각 파일 시스템을 가지고 있음
- 디스크 할당
- 순차 접근 저장장치
- 앞에서부터 순서대로 읽어야 하는 저장 장치
- 원하는 지점 찾기 어렵고 빨리 감기와 되감기 기능이 필요
- 직접 접근 저장장치
- 헤드를 옮겨 원하는 부분부터 접근 가능
- 모든 데이터 읽지 않고도 바로 원하는 곳에 접근 가능
- 하드디스크
- 하드디스크는 플래터(원판, LP판과 비슷)를 여러장 쌓아놓고 돌림
- 플래터 사이사이 정보를 읽고 쓸 수 있는 헤드가 들어가 있고 플래터가 회전하고 헤드가 정보 읽어옴
- 플래터에서 띠 모양의 영역은 트랙, 하드 드라이브의 최소 기억 단위는 섹터
- SSD
- 하드 디스크와 달리 물리적 기계장치가 없이 전기 장치로만 구성
- 모터 같은 기계 장치 없어서 하드 디스크에 비해 훨씬 빠름
- 순차 접근 저장장치
- 파일 할당
- 하드 디스크는 블록이라는 단위로 나누어 번호를 붙임
- 파일 저장 방법이 여러가지 있음
- 연속 할당
- 앞에서 부터 차례대로
- 헤드 이동 최소화해서 입출력 속도 빠름
- 순차 접근과 직접 접근 모두 가능
- 할당과 삭제 반복하면 중간에 구멍 생기는 외부 단편화 발생
- 파일 계속 커지는 경우 부적절
- 연결 할당
- 연결리스트와 같은 방식으로 파일 할당
- 데이터와 주소를 저장하는 공간으로 나눠서 사용
- 외부 단편화 문제 x
- 헤드가 여러번 움직여야 하며 직접 접근 불가능 → 화살표 따라가지 않으면 다음 위치 알 수 없음. 한 파일은 무조건 처음부터 접근해야 함
- 한 칸 손상되면 나머지 모든 데이터 읽을 수 없음
- FAT 방식
- 화살표를 모아서 하나의 표로 저장
- 각 칸이 다음은 어디로 연결되는지 FAT라는 테이블에 기록
- FAT만 읽어 두면 원하는 칸부터 접근하는 직접 접근도 가능
- 손상되어도 FAT를 보면 다음 칸 어디인지 알 수 있음
- 한계: FAT 크기에 따라 최대 파일 크기와 파티션 크기가 제한 → 칸 번호의 자릿수를 늘리면 표가 커질수록 검색 시간 증가, 칸 크기 늘리면 작은 파일도 큰 칸에 저장하면서 단편화 발생
- 발전: FAT에서 주소 표시하는 비트 수 변경하면서 발전. 칸 번호를 몇 비트로 기록할 것인지에 따라 버전 달라짐.(FAT16, FAT32) 표가 아닌 트리 형태로 저장하는 NFTS 방식도 등장
- 색인 할당
- 번호들을 순서대로 한 칸에 기록. 번호들이 기록된 칸을 인덱스 블록이라 부름
- 인덱스 블록을 읽으면 직접 접근이 가능하며 외부 단편화 문제가 발생하지 않음
- 표를 저장하기 위해 파일마다 한 칸을 사용해야 함. 한 칸에 들어갈 수 없을 정도로 큰 파일은 저장 불가능
- 링크
- 리눅스의 inode(index node)
- 리눅스에서 색인할당과 유사한 inode로 파일 관리
- 파일에 대한 모든 정보(권한, 유형 등)가 기록
- 각 노드에 번호를 부여
- 모든 파일과 디렉토리는 고유한 inode 가짐
- 바로가기
- 파일의 일종
- 바로가기 삭제해도 원본 파일 삭제 x
- 바로가기 실행은 해당 파일 실행하는 것과 동일
- 리눅스의 바로가기 기능
- 심볼릭 링크
- 윈도우의 바로가기 기능에 해당
- 심볼릭 링크 파일도 별도의 고유한 inode를 가지고 파일 내용으로 원본 파일의 경로를 가짐
- 원본 파일이 삭제되거나 경로가 변하면 링크가 끊어짐
- 링크 파일 수정하면 원본 파일의 내용이 동일하게 수정
- 하드링크
- 원본 삭제해도 inode 가리키는 하드 링크 파일이 남아있음
- 원본 파일을 삭제하든 이동하든 영향 받지 않고 하드 링크 파일을 그대로 사용할 수 있음
- 링크 파일 수정하면 원본 파일도 수정
- 링크가 원본파일의 inode를 공유함
- (리눅스) 링크는 ln 명령어 사용 -s 사용하면 심볼릭 링크를, 사용하지 않으면 하드 링크를 생성함.
- 링크 활용 방법
- 대량의 데이터를 복사하는 대신 사용
- 여러 위치에 같은 데이터가 저장된 것처럼 사용할 수 있지만, 하드 디스크 용량은 한 번만 차지하고 있음
- 수정하면 원본도 같이 수정되는 점 유의하면서 사용해야함
- 리눅스의 inode(index node)
- 마운트
- 물리적인 장치를 특정 디렉토리에 연결하는 것
- 새로운 물리 장치 사용을 위해 반드시 마운트를 해야함
- 일부 운영체제에서는 자동으로 마운트 실행
- 마운트 필요 이유
- 마운트를 해야 운영체제가 저장 장치를 인식하여 접근 가능
- 저장 장치의 파일 시스템에 접근하려면 먼저 인식시키는 작업 필요
- 운영체제가 저장 장치 인식하도록 하는 작업이 마운트
- 대부분의 저장장치 → 하드디스크, USB 메모리, CD, DVD, 플로피 디스크 등
- 윈도우에서는 하드디스크-C, USB-D, CD-E, 플로피-A로 자동으로 마운트
- 리눅스는 root라는 디렉토리가 하드 디스크에 마운트.
- 마운트된 디렉토리: 마운트 포인트마운트의 대상
- 마운트 코드
- lsblk -p: 파일 시스템의 목록 확인
- TYPE → disk / part: 파티션(디스크 하나를 여러개로 나눈 것)
- sudo mount [옵션] [장치] [디렉토리]: 마운트하기
운영체제의 종류
- 윈도우: 마이크로소프트사. 유료
- 맥: 유닉스 기반. 유료
- 리눅스: 무료에 안정적인 운영체제. 우분투, 데비안 같은 배포판 존재
- 컨테이너화: 실행에 필요한 모든 환경과 패키지를 포함하여 하나로 묵는 기술. 사용하고 있는 운영체제에 상관없이 동일한 개발환경 구성 가능 → Docker
반응형
'IT Study > CS' 카테고리의 다른 글
[Front] 디바운싱과 쓰로틀링 (1) | 2023.11.22 |
---|---|
[CS] Stateful vs Stateless 차이 (0) | 2023.11.15 |
[Back] 계속 헷갈리는 토큰 vs 쿠키 vs 세션 (1) | 2023.11.14 |
[Back] CORS ERROR와 CORS 옵션 (1) | 2023.11.12 |
[CS] 컴퓨터 구조 (Feat. 11주차) (0) | 2023.10.31 |