혼자 공부하면서 노션에 적어둔 내용을 기록할겸 붙여넣기 했습니다 (정리 안 됨 말 그대로 낙서)
프로세스, 스레드, 멀티태스킹, 멀티스레딩, 멀티프로세싱, 멀티프로그래밍
- 프로그램
- 컴퓨터가 실행할 수 있는 명령어들의 집합
- 프로세스
- 컴퓨터에서 실행 중인 프로그램
- 각각의 프로세스는 독립된 메모리 공간을 할당 받음
- 명령어들과 데이터를 가짐
- CPU
- 명령어를 실행하는 연산 장치
- 메인 메모리
- 프로세스가 CPU에서 실행되기 위해 대기하는 곳
- IO
- 입출력
- 단일 프로그램 → 한 번에 하나의 프로그램만 실행 됨 → CPU 사용률 좋지 않음
⇒ 여러 개의 프로그램을 메모리에 올려놓고 동시에 실행 시키자 → IO 작업이 발생하면 다른 프로세스가 CPU에서 실행됨
- 멀티 프로그래밍
- CPU 사용률을 극대화 시키는데 목적
- 단점: CPU 사용 시간이 길어지면 다른 프로세스는 계속 대기
- 멀티 태스킹
- 짧게 쪼개서 프로세스들이 번갈아가면서 실행 → 동시에 여러 프로그램이 실행되는듯한 느낌을 줌
- 프로세스의 응답 시간을 최소화 시키는데 목적
- 스레드 특징
- 프로세스는 한 개 이상의 스레드를 가질 수 있다
- 같은 프로세스의 스레들끼리 컨텍스트 스위칭은 가볍다
- 스레드들은 자신들이 속한 프로세스의 메모리 영역을 공유
- 프로그램 카운터
- 다음에 실행되어야할 명령어가 있는 메모리 주소를 가리킴
- 멀티 스레딩
- 하나의 프로세스가 동시에 여러 작업을 실행하는데 목적
- 멀티 프로세싱
- 두 개 이상의 프로세서나 코어를 활용하는 시스템
컨텍스트 스위칭
- 컨텍스트 스위칭
- CPU/코어에서 실행 중이던 프로세스/스레드가 다른 프로세스/스레드로 교체되는 것
- 왜 필요?
- 여러 프로세스/스레드를 동시에 실행시키기 위해서
- 언제 발생?
- 주어진 time slice를 다 사용했거나
- IO 작업을 해야하거나
- 다른 리소스를 기다려야 하거나
- 누구에 의해 실행?
- OS 커널 - 각종 리소스를 관리 / 감독하는 역할
- 프로세스 컨텍스트 스위칭 , 스레드 컨텍스트 스위칭
- 커널 모드에서 실행
- CPU의 레지스터 상태를 교체
- 프로세스 컨텍스트 스위칭 → 가상 메모리 주소 관련 처리를 추가로 수행
- 레지스터의 TLB ㅂ비워줘야됨
- 스레드 컨텍스트 스위칭이 더 빠른 이유?
- 메모리 주소 관련 처리는 하지 않기 때문
- 같은 메모리를 공유하기 대문ㅇ=ㅇ-
- 컨텍스트 스위칭이 미치는 간접적인 영향
- 캐시 오염
- 유저 관점에서 컨텍스트 스위칭이란?
- 순수한 오버헤드
cpu bound, io bound → 스레드 개수를 결정하는데 어떤 영향을 주는지
- CPU
- 프로세스의 명령어를 해석하고 실행하는 장치
- IO
- 파일을 읽고 쓰거나
- 네트워크의 어딘가와 데이터를 주고 받는 것
- 입출력 장치와 데이터를 주거나 받는 것
- 버스트 (burst)
- 어떤 현상이 짧은 시간 안에 집중적으로 일어나는 일
- CPU 버스트
- 프로세스가 CPU에서 한번에 연속적으로 실행되는 시간
- IO 버스트
- 프로세스가 IO 작업을 요청하고 그 결과를 기다리는 시간
- 프로세스의 인생은 CPU 버스트와 IO 버스트의 연속
- CPU bound 프로세스
- CPU 버스트가 많은 프로세스
- 예) 동영상 편집 프로그램, 머신러닝 프로그램
- IO bound 프로세스
- IO 버스트가 많은 프로세스
- 예) 일반적인 백엔드 API 서버
- CPU bound 프로그램에서 적절한 스레드 수: CPU 개수 + 1
- IO bound 프로그램에서 적절한 스레드 수: 상황에 맞춰서 적절한 스레드 수를 찾아야됨
동기화(synchronization), 경쟁 조건(race condition), 임계 영역(critical section)
- 경쟁 조건 (race Condition)
- 여러 프로세스/스레드가 동시에 같은 데이터를 조작할 때 타이밍이나 접근 순서에 따라 결과가 달라질 수도 있는 상황
- 동기화(synchronization**)**
- 여러 프로세스/스레드를 동시에 실행해도 공유 데이터의 일관성을 유지하는 것
- 임계 영역 (critical section**)**
- 공유 데이터의 일관성을 보장하기 위해 하나의 프로세스/스레드만 진입해서 실행 가능한 영역
- critical section problem 의 해결책이 되기 위한 조건
- mutual exclusion (상호 배제)
- progress (진행)
- bounded waiting (한정된 대기)
동기화 여러 전략 및 차이 - 스핀락(spinlock) 뮤텍스(mutex) 세마포(semaphore) 각각의 특징과 차이
- mutual exclusion (상호 배제)
- 스핀락(spinlock)
- 락을 가질 수 있을때까지 반복해서 시도
- → 기다리는 동안 CPU 낭비
- 뮤텍스 (mutex)
- 락을 가질 수 있을 때까지 휴식
- 뮤텍스가 스핀락보다 항상 좋을까?
- → X : 멀티코어 환경이고 임계 영역에서의 작업이 컨텍스트 스위칭보다 빨리 끝난다면 스핀락이 뮤텍스보다 더 이점이 있음
- 세마포 (semaphore)
- signal mechanism 을 가진 하나 이상의 프로세스 / 스레드 가 임계영역에 접근 가능하도록 하는 장치
- 뮤텍스 vs 바이너리 세마포
- 뮤텍스는 락을 가진 자만 락을 해제 할 수 있음 , 세마포는 그렇지 않음
- 뮤텍스는 priority inheritance 속성을 가짐, 세마포는 그 속성이 없음
- 상호배제만 필요하다면 → 뮤텍스
- 작업 간의 실행 순서 동기화가 필요하면 → 세마포
모니터가 어떻게 동기화에 사용되는지
- 모니터
- mutual exclusion 을 보장
- 조건에 따라 스레드가 대기 상태로 전환 가능
- 언제 사용?
- 한번에 하나의 스레드만 실행해야할 때
- 여러 스레드와 협업이 필요할때
- 모니터의 구성요소
- mutex
- condition variable
- mutex
- 임계 영역에서 mutual exclusion을 보장하는 장치
- 임계영역에 진입하려면 Mutex lock을 취득해야함
- Mutex lock을 취득하지 못한 스레드는 큐에 들어간 후 대기 상태로 전환
- Mutex lock을 쥔 스레드가 lock을 반환하면 락을 기다리며 큐에 대기 상태로 있던 스레드 중 하나가 실행
- condition variable
- waiting queue를 가짐
- 조건이 충족되길 기기다리는 스레드들이 대기 상태로 머무는 곳
- 주요동작
- wait
- 스레드가 자기 자신을 condition variable의 waiting queue에 넣고 대기 상태로 전환
- signal
- waiting queue 에서 대기중인 스레드 중 하나를 깨움
- broadcast
- waiting queue에서 대기 중인 스레드를 전부를 깨움
- wait
- entry queue: 임계영역에 진입을 기다리는 큐
- waiting queue : 조건이 충족되길 기다리는 큐 →condition variable에 의해 관리되는 큐
데드락(교착상태) 의 발생과 해결 방법
- 데드락(교착상태)
- 두 개 이상의 프로세스 혹은 스레드가 서로가 가진 리소스를 기다리는 상태
- 데드락의 네가지 조건 (모두 만족해야 데드락 발생)
- Mutual exclusion
- 리소스를 공유해서 사용할 수 없다.
- Hold and wait
- 프로세스가 이미 하나 이상의 리소스를 취득한(hold) 상태에서 다른 프로세스가 사용하고 있는 리소스를 추가로 기다린다(wait)
- No preemption
- 리소스 반환은 오직 그 리소스를 취득한 프로세스만 할 수 있다.
- Circular wait
- 프로세스들이 순환 형태로 서로의 리소스를 기다린다.
- Mutual exclusion
- 해결 방법: 데드락 방지, 데드락 회피, 데드락 감지와 복구, 데드락 무시
- 데드락 방지
- 네 가지 조건 중 하나가 충족되지 않게 시스템을 디자인
- mutual exclusion → 리소스를 공유 가능하게 함 ( 프린터 같이 mutual exclusion 이 보장되어야하는 리소스가 있기 때문에 현실적으로 불가능)
- Hold and wait
- 사용할 리소스들을 모두 획득한 뒤에 시작
- 리소스를 전혀 가지지 않은 상태에서만 리소스 요청
- 단점: 리소스 사용 효율 떨어짐, 기아 현상
- No preemption
- 추가적인 리소스를 기다려야 한다면 이미 획득한 리소스를 다른 리소스가 선점 가능하도록 한다.
- Circular wait
- 모든 리소스에 순서 체계를 부여해서 오름차순으로 리소스를 요청
- 제일 많이 사용
- 데드락 회피
- 실행 환경에서 추가적인 정보를 활용해서 데드락이 발생할 것 같은 상황을 회피하는 것
- Banker algorithm
- 리소스 요청을 허락해줬을 때 데드락이 발생할 가능성이 있으면 리소스를 할당해도 안전할 때 까지 계속 요청을 거절 하는 알고리즘
- 데드락 감지와 복구
- 데드락을 허용하고 데드락이 발생하면 복구하는 전략
- 복구 전략
- 프로세스를 종료한다
- 리소스의 일시적인 선점을 허용한다.
- 데드락 무시
- 운영체제에서 데드락 무시
OS 프로세스의 상태 변화
- OS에서 프로세스의 상태
new → Long term 스케줄러 → ready → short term 스케줄러 → running → 할당된 time slice 쓰면 → Ready
IO 작업 또는 임계 영역을 쓰고 싶은데 기다리게 된다 → Waiting → 완료 → ready → 스케줄러가 너차례임 하면→ running
동작하다가 프로세스가 마무리를 해야하면 running 상태로 바꾼 뒤 마무리 작업 실행 → terminated
- 자바 스레드의 상태 종류
- NEW - 자바 스레드가 아직 시작하지 않은 상태
- RUNNALBE - 실행 중인 상태, 다른 리소스를 기다리는 상태도 포함
- BLOCKED - 임계 영역으로 들어가려고 모니터 락을 얻기 위해 기다리는 상태
- WAITING - 다른 스레드를 기다리는 상태
- TIMED_WAITING - 제한 시간을 두고 다른 스레드를 기다리는 상태
- TERMINATED - 실행을 마치고 종료된 상태
CPU 스케줄러, 디스패처, 스케줄링의 선점 방식
- Cpu 스케줄러 vs 디스패처
- CPU 스케줄러 : CPU 에서 실행될 프로세스를 선택하는 역할
- 디스패처 : 그렇게 선택된 프로세스를 실제로 CPU에서 실행될 수 있도록 → 컨텍스트 스위칭, 커널모드에서 유저 모드로 전환, 실행되어야할 적절한 위치로 이동 시키는 역할
- → 선택된 프로세스에게 CPU를 할당하는 역할
- 스케줄링의 선점 방식
- 선점, 비선점이 있음
- 비선점 : 신사적, 협력적, 느린 응답성
- 선점: CPU에서 실행중인데도 개입해서 뺏어옴 → 적극적, 강제적, 빠른 응답성, 데이터 일관성 문제
- 스케줄링 알고리즘
- FCFS (first- come, first-served)
- 먼저 도착한 순서대로 처리
- SJF (shortest-job- first)
- 프로세스의 다음 CPU 버스트가 가장 짧은 프로세스 부터 실행
- SRTF (shortest-remaining-time-first)
- 남은 CPU 버스트가 가장 짧은 프로세스부터 실행
- Priority Scheduling
- 우선순위가 높은 프로세스부터 실행
- Round-robin 라운드로빈
- time slice 로 나눠진 CPU time을 번갈아가며 실행
- Multilevel queue
- 프로세스들을 그룹화해서 그룹마다 큐를 두는 방식
- FCFS (first- come, first-served)
인터럽트와 시스템 콜, 유저모드, 커널모드 , 프로그래밍 언어와의 관계
- 유저모드 - 우리가 개발하는 프로그램은 일반적으로 유저모드에서 실행
- 유저모드 → 커널모드 - 프로그램 실행 중에 인터럽트가 발생하거나 시스템 콜을 호출하게 되면 커널 모드로 전환
- 커널모드 - 프로그램의 현재 CPU 상태를 저장함, 커널이 인터럽트나 시스템 콜을 직접 처리 → CPU에서 커널 코드가 실행 → 처리가 완료되면 중단됐던 프로그램의 CPU 상태를 복원
- 커널모드 → 유저모드 - 다시 통제권을 프로그램에게 반환
- 유저모드 - 프로그램이 이어서 실행됨
- 커널
- 운영체제의 핵심
- 시스템의 전반 관리 / 감독하는 역할
- 하드웨어와 관련된 작업을 직접 수행
- 그럼 왜 만듦?
- 시스템을 보호하기 위해
- 인터럽트
- 시스템에서 발생한 다양한 종류의 이벤트 혹은 그 이벤트를 알리는 메커니즘
- 전원에 문제가 생겼을 때
- IO 작업이 완료됐을 때
- 시간이 다 됐을 때
- 0으로 나눴을 때
- 잘못된 메모리 공간에 접근을 시도할 때
- 인터럽트가 발생하면 CPU에서 즉각적으로 인터럽트 처리를 위해 커널코드를 커널 모드에서 실행
- 시스템에서 발생한 다양한 종류의 이벤트 혹은 그 이벤트를 알리는 메커니즘
- 시스템 콜
- 프로그램이 OS 커널이 제공하는 서비스를 이용하고 싶을 때 시스템 콜을 통해 실행
- 프로세스 / 스레드 관련
- 파일 IO 관련
- 소켓 관련
- 장치 관련
- 프로세스 통신 관련
- 시스템 콜이 발생하면 해당 커널 코드가 커널 모드에서 실행
- 프로그램이 OS 커널이 제공하는 서비스를 이용하고 싶을 때 시스템 콜을 통해 실행
- 프로그래밍 언어와 시스템 콜의 관계
- 하드웨어 혹은 시스템 관련 기능은 어떤 프로그램이라도 반드시 시스템 콜을 통해서만 사용 가능
- → 어케함?
스레드의 종류
- 하드웨어 스레드, OS 스레드, 네이티브 스레드, 커널 스레드, 유저 스레드, 그린 스레드
- 하드웨어 스레드
- 코어의 고민 → 메모리에서 데이터를 기다리는 시간이 꽤 오래 걸린다..
- 메모리는 기다리는 동안 다른 스레드를 실행하는 건 어떰?
- OS 관점에서는 가상의 코어
- 만약에 싱글 코어 CPU에서 하드웨어 스레드가 두 개라면 OS 는 이 CPU를 듀얼 코어로 인식하고 듀얼 코어에 맞춰서 OS 레벨의 스레드들을 스케줄링한다
- OS 스레드
- CPU에서 실제로 실행되는 단위, CPU 스케줄링의 단위
- OS 스레드의 컨텍스트 스위칭은 커널이 개입 → 비용 발생
- 사용자 코드와 커널 코드 모두 OS 스레드에서 실행됨
- OS 스레드 = 네이티브 스레드 = 커널 스레드 = 커널-레벨 스레드 = OS-레벨 스레드
- 유저 스레드
- 유저-레벨 스레드라고 불림
- 스레드 개념을 프로그래밍 레벨에서 추상화한 것
- 유저 스레드가 CPU에서 실행되려면 OS 스레드와 반드시 연결돼야 한다.
- 유저스레드와 OS 스레드를 어떻게 연결 할것인가
- One-to-One model
- 1대1 관계
- 스레드 관리를 OS 에 위임
- 스케줄링 커널이 수행
- 멀티 코어도 잘 활용함
- 한 스레드 블락 → 다른 스레드 잘 동작
- 경쟁 조건 발생 가능성
- 오늘날의 자바
- Many-to-One model
- 유저스레드: OS스레드 = n 대 1 관계
- 커널 개입 X
- 유저 스레드 간의 스위칭이 빠름
- OS 레벨에서 경쟁 조건 발생 가능성 낮다
- 경쟁 조건 발생 가능성 낮음
- 컨텍스트 스위칭이 훨씬 빨리 끝남
- 멀티 코어 활용 못함
- 한 스레드 블락 → 모든 스레드 블락 ⇒ 이 문제 해결하기 위해 non block IO
- Many-to-Many model
- n 대 n 관계
- 1대1 관계, n대1관계 장점 합쳐서 만듦
- 유저스레드 스위칭 빠름
- 멀티코어 활용
- 한 스레드 블락 → 다른 스레드 잘 동작
- 구현이 복잡함
- One-to-One model
- 조금 다른 의미의 유저스레드 : OS와는 독립적으로 유저레벨에서 스케줄링 되는 스레드
- 그린 스레드
- 자바 초창기 버전은 Many-to-One 스레딩 모델을 사용 → 이 떄 이 유저 스레드들을 그린 스레드라고 호칭
- OS와는 독립적으로 유저레벨에서 스케줄링되는 스레드
- 조금 다른 맥락에서 커널 스레드
- OS 커널의 역할을 수행하는 스레드
스레드 풀
서버에 들어오는 요청마다 스레드를 새로 만들어서 처리하고 처리가 끝난 스레드는 버리는 식으로 동작한다면 어떤 문제점이 있을까?
- 스레드 생성에 소요되는 시간 때문에 요청 처리가 더 오래 걸림
- 처리 속도보다 더 빠르게 요청이 늘어나면 → 스레드 계속 생성 (스레드 수 증가) → 컨텍스트 스위칭이 더 자주 발생 → CPU 오버헤드 증가로 CPU time 낭비 → 어느 순간 서버 전체가 응답 불가능 상태에 빠짐
- 처리 속도보다 더 빠르게 요청이 늘어나면 → 스레드가 계속 생성(스레드 수 증가) → 메모리가 점점 고갈됨
⇒ 해결하기 위해 스레드 풀 개념 등장
- 스레드 풀
- 미리 스레드를 여러 개 만들어 놓고 재사용 → 스레드 생성 시간 절약
- 제한된 개수의 스레드를 운용 → 스레드가 무제한으로 생성되는 것을 방지
- 스레드 풀 사례 : 여러 작업을 동시에 처리해야할 때
- thread per request 모델
- task 를 subtask로 나누어서 동시에 처리
- 순서 상관없이 동시 실행이 가능한 태스크 처리
- 스레드 풀 사용 팁
- 스레드 풀에 몇개의 스레드를 만들어 두는게 적절한가?
- CPU-bound 태스크라면 코어 개수만큼 혹은 그 보다 몇 개 더 많은 정도
- IO -bound 태스크라면 경험적으로 찾아야 함
- 스레드 풀에서 실행될 태스크 개수에 제한이 없다면 스레드 풀의 큐가 사이즈 제한이 있는지 꼭 확인할 것
- 사이즈 제한 없는 큐는 상황에 따라서는 메모리를 고갈시키는 잠재적인 위험 요인이 될 수 있음
- pool 이라는 개념은 스레드에서만 쓰이는 것은 아님
- 커넥션 풀, 프로세스 풀 등
block I/O vs non-block I/O
IO - input / output 데이터의 입출력
네트워크(소켓), 파일, 파이프, 디바이스
- 소켓
- 네트워크 통신은 소켓을 통해 데이터가 입출력 된다
- 백엔드 서버
- 네트워크 상의 요청자들과 각각 소켓을 열고 통신한다
- Block I/O
- I/O 작업을 요청한 프로세스 / 스레드는 요청이 완료될 때까지 블락됨
- non-block I/O
- 프로세스/스레드를 블락시키지 않고 요청에 대한 현재 상태를 즉시 리턴
- 블락되지 않고 즉시 리턴하기 때문에 스레드가 다른 작업을 수행할 수 있음
- 이슈
- I/O 작업 완료를 어떻게 확인 할거임?
- non blcok I/O 결과 처리 방식
- 완료 됐는지 반복적으로 확인
- 완료된 시간과 완료를 확인한 시간 사이의 갭으로 인해 처리 속도가 느려질 수 있음
- 완료됐는지 반복적으로 확인하는 것은 CPU 낭비 발생
- I/O multiplexing (다중 입출력) 사용
- 관심있는 I/O 작업들을 동시에 모니터링 하고 그 중에 완료된 I/O 작업들을 한 번에 알려줌
- 네트워크 통신에 많이 사용
- Callback/signal 사용
- 완료 됐는지 반복적으로 확인
핵심은 non-block I/O 를 통해 I/O 요청 완료 전에도 다른 일을 할 수 있다는 것
동기 비동기
프로그래밍 관점
- Synchronous (동기)
- 여러 작업들을 순차적으로 실행하도록 개발
- Asynchronous (비동기
- 여러 작업들을 독립적으로 실행하도록 개발
- Asynchronous ≠ 멀티스레딩
- Asynchronous
- 여러 작업을 동시에 실행하는 프로그래밍 방법론
- 멀티스레딩
- Asynchronous 프로그래밍의 한 종류
- Asynchronous
- Asynchronous
- non-block I/O
- 스레드를 적게 쓰면서도 non-block I/O를 통ㅇ해 전체 처리량을 늘리는 방향으로..
IO 관점
- case1
- synchronous I/O = block I/O
- Asynchronous I/O = non-block I/O
- case 2
- synchronous I/O : 요청쟈가 I/O 완료까지 챙겨야할 때
- Asynchronous I/O : 완료를 noti 주거나 콜백으로 처리
- case 3
- Asynchronous I/O : block I/O를 다른 스레드에서 실행
백엔드 아키텍처 관점
- 하나의 서비스는 기능과 역할에 따라 여러 개의 마이크로 서비스로 구성되고 이들 사이에서는 빈번하게 커뮤니케이션이 발생
- synchronous 커뮤니케이션
- Asynchronous 커뮤니케이션
---
PHASE 2
운영체제의 역할
- CPU 스케줄링과 프로세스 관리
- CPU 소유권을 어떤 프로세스에 할당할지, 프로세스의 생성과 삭제, 자원 할당 및 반환 관리
- 메모리 관리
- 한정된 메모리를 어떤 프로세스에 얼마큼 할당해야 하는지 관리
- 디스크 파일 관리
- 디스크 파일을 어떠한 방법으로 보관할지 관리
- I/O 디바이스 관리
- I/O 디바이스들 간의 데이터를 주고받는 것을 관리
컴퓨터의 요소
CPU, DMA 컨트롤러, 메모리, 타이머,디바이스 컨트롤러 등으로 이루어짐
CPU
산술논리연산장치, 제어장치, 레지스터로 구성
- 제어장치 ( CU )
- 프로세스 조작을 지시
- 입출력 장치간 통신 제어
- 명령어 해석 및 데이터 처리를 위한 순서 결정
- 레지스터
- CPU 안에 있는 매우 빠른 임시기억장치
- 연산 속도 빠름
- CPU 는 자체적으로 데이터를 저장할 방법이 없음 → 레지스터를 거쳐 데이터를 전달
- 산술 논리연산장치 ( ALU )
- 산술 연산, 논리연산 계산
CPU 의 연산 처리
- 제어장치가 메모리에 계산할 값 로드 , 레지스터에도 로드
- 제어장치가 레지스터에 있는 값을 계산하라고 ALU 에 명령
- 제어장치가 계산된 값을 다시 레지스터에서 메모리로 계산한 값을 저장
DMA 컨트롤러
I/O 디바이스가 메모리에 직접 겁근할 수 있도록 하는 하드웨어 장치
CPU 부하를 막아줌
메모리
전자회로에서 데이터나 상태, 명령어 등을 기록하는 장치
CPU는 계산을 담당, 메모리는 기억을 담당
타이머
몇 초 안에는 작업이 끝나야 한다는 것을 정하고 특정 프로그램에 시간 제한을 다는 역할
시간이 많이 걸리는 프로그램이 작동할 때 제한을 걸기 위해 존재
디바이스 컨트롤러
컴퓨터와 연결되어있는 IO 디바이스들의 작은 CPU
메모리
메모리 계층
- 레지스터
- CPU 안에 있는 작은 메모리
- 휘발성, 속도 제일 빠름, 기억 용량 가장 작음
- 캐시
- L1, L2 캐시를 지칭
- 휘발성, 속도 빠름, 기억 용량 작음
- 주기억장치
- RAM
- 휘발성, 속도 보통, 기억용량 보통
- 보조기억장치
- HDD, SSD
- 비휘발성, 속도 낮음, 기억용량 많음
속도, 가격: 레지스터 > 캐시 > 주기억장치 (RAM) > 보조기억장치
용량 : 보조기억장치 > 주기억장치(RAM) > 캐시 > 레지스터
램은 하드디스크로부터 일정량의 데이터를 복사해서 임시 저장하고 필요 시마다 CPU에 빠르게 전달하는 역할
캐시
데이터를 미리 복사해 놓는 임시 저장소
빠른 장치와 느린 장치에서 속도 차이에 따른 병목 현상을 줄이기 위한 메모리
→ 데이터를 접근하는 시간이 오래 걸리는 경우를 해결, 다시 계산하는 시간을 절약
- 시간 지역성 : 최근 사용한 데이터에 다시 접근하려는 특성
- 공간 지역성 : 최근 접근한 데이터를 이루고 있는 공간이나 그 가까운 공간에 접근하는 특성
- Hit : 원하는 데이터 찾음
- Miss : 캐시에 없음 ( 주메모리로가서 데이터 찾아와야 함)
- 캐시 매핑
- 직접 매핑 (directed mapping)
- 각 메모리 위치가 캐시내에서 정확히 한 곳에만 매핑 되는 구조
- 장점: 구현 단순, 접근속도 빠름
- 단점: 충돌발생, 낮은 적중률
- 연관 매핑 (Fully Associate Mapping)
- 빈자리 찾아감. 캐시 블록 번호는 메모리 블록 번호와 무관, 메모리 블록의 어떤 정보도 포함하지 않음
- 장점: 직접 매핑보다 적중률 높음
- 단점: 속도 느림, 고가의 메모리 필요
- 집합 연관 매핑 (Set Associate Mapping)
- 직접과 연관을 절충
- 직접 매핑 처럼 메모리 블록은 정해진 인덱스만 들어갈 수 있지만, 블록이 여러개의 집합으로 이루어져서 그 집합 내에 아무자리나 들어가면 됨
- 적중률 : 직접 < 집합 < 완전 연관
- 직접 매핑 (directed mapping)
- 캐시가 히트되기 위해 매핑하는 방법
- 캐싱 전략
- Write-through
- 데이터를 추가하거나 업데이트를 할 때 캐시에 동시에 업데이트를 하는 전략
- Write Through 정책은 메인 메모리를 바로 업데이트하는 방식이다.
- 캐시와 메인 메모리의 일관성을 유지할 수 있지만 , 값이 바뀔때마다 매번 변경해줘야 하므로 속도가 느리다는 단점이 있다.
- 장점 : 둘 다 업데이트해서 일관성 유지, 안정적
- 단점 : 속도가 느린 장치를 쓰면 성능이 느림
- Write-back
- 데이터를 캐시에 먼저 저장해놓고 일정 기간 혹은 일정한 크기가 됐을 때, 캐시에 모여있는 데이터를 DB에 저장한 후 캐시에 있던 데이터를 삭제하는 방식
- 장점 : 속도 빠름
- 단점: 서로 다른 값이 발생할 수 있음
- Write-through
- 캐시 write를 어디다 하느냐에 대한 관점
웹 브라우저의 캐시
- 쿠키
- 만료 기한 있는 키-값 저장소
- 4KB까지 데이터 저장
- 만료 기한 정할 수 있음
- 로컬 스토리지
- 만료 기한 없는 키-값 저장소
- 10MB까지 저장 가능
- 웹 브라우저를 닫아도 유지 됨
- 도메인 단위로 저장, 생성
- 클라이언트에서만 수정 가능
- 세션 스토리지
- 만료 기한 없는 키-값 저장소
- 탭 단위로 세션 스토리지를 생성
- 탭을 닫을 때 삭제
- 5MB까지 저장 가능
- 클라이언트에서만 수정 가능
메모리 관리
가상 메모리
실제로 이용가능한 메모리 자원을 추상화 → 사용자들에게 매우 큰 메모리로 보이게 만듦
- 가상 주소 (logical address)
- 실제 주소 (physical address)
- 가상 주소와 실제 주소가 매핑 되어있음
- 프로세서의 주소 정보가 들어있는 페이지테이블로 관리 → 속도 향상을 위해 TLB 사용
- TLB
- 메모리와 CPU 사이에 있는 주소 변환을 위한 캐시
- 페이지 테이블에 있는 리스트 보관
- CPU가 페이지 테이블까지 가지 않도록 해 속도 향상
- 스와핑
- 가상메모리에는 존재하지만 실제 메모리인 RAM에는 없는 데이터나 코드에 접근 할 경우 페이지 폴트 발생
- → 사용하지 않는 영역을 하드디스크로 옮기고 하드디스크의 일부분을 마치 메모리처럼 불러와 쓰는 것
- 페이지 폴트
- 프로세스 주소 공간에는 존재하지만 RAM에는 없는 데이터에 접근 했을 경우에 발생
- CPU는 물리 메모리를 확인 → 해당 페이지가 없으면 트랩을 발생해서 운영체제에게 알림
- 운영체제는 CPU의 동작을 잠시 멈춤
- 운영체제는 페이지 테이블을 확인 → 가상 메모리에 페이지 존재유무 확인 → 없으면 프로세스 중단하고 현재 물리 메모리에 비어있는 프레임이 있는지 확인 → 물리 메모리에도 없으면 스와핑
- 비어있는 프레임에 해당 페이지 로드 → 페이지 테이블 최신화
- CPU 재시작
스레싱
메모리의 페이지 폴트율이 높은 것 → 컴퓨터의 성능 저하 초래
메모리에 너무 많은 프로세스가 동시에 올라가게되면 스와핑이 많이 일어남
페이지 폴트가 일어나면 CPU 이용률 낮아짐 → 가용성을 높이기 위해 프로세스를 메모리에 올림 → 악순환
- 해결 방법
- 메모리 늘림
- HDD → SDD 바굼
- 작업세트
- PFF
- 작업 세트
- 프로세스의 과거 사용 이력인 지역성을 통해 결정된 페이지 집합을 만들어서 미리 메모리에 로드하는 것
- PFF (Page Fault Freqeuncy)
- 페이지 폴트 빈도를 조절하는 방법
- 상한선 하한선 만듦
- 상한선 도달 → 프레임 늘림
- 하한선 도달 → 프레임 줄임
메모리 할당
- 연속할당
- 고정 분할 방식
- 메모리를 미리 나누어 관리
- 융통성 없음, 내부 단편화 발생
- 내부단편화: ( 크기 > 프로그램 )
- 외부단편화: (크기 < 프로그램)
- 가변 분할 방식
- 매 시점 프로그램의 크기에 맞게 동적으로 메모리를 나눠 사용
- 외부 단편화 발생
- 최초적합 (first fit)
- 위쪽이나 아래쪽부터 시작해서 홀을 찾으면 바로 할당
- 최적적합 (best fit)
- 프로세스 크기 이상인 공간 중 가장 작은 홀부터 할당
- 최악적합 (worst fit)
- 프로세스의 크기와 가장 많이 차이가 나는 홀에 할당
- 고정 분할 방식
- 연속적으로 공간 할당
- 불연속 할당
- 페이징
- 동일한 크기의 페이지 단위로 나누어 메모리의 서로 다른 위치에 프로세스를 할당
- 홀의 크기가 균일하지 않은 문제가 없어짐
- 주소 변환 복잡
- 세그멘테이션 (segmentation)
- 페이지 단위가 아닌 의미 단위인 세그먼트로 나누는 방식
- 공유와 보안 측면에서 좋음
- 홀 크기가 균일하지 않음
- 페이지드 세그멘테이션
- 공유나 보안을 의미 단위의 세그먼트로 나누고 물리적 메모리는 페이지로 나눔
- 페이징
- 불연속적으로 공간 할당
페이지 교체 알고리즘
메모리는 한정되어 있음 → 스와핑이 많이 일어남 → 스와핑이 많이 일어나지 않도록 설계
- 오프라인 알고리즘
- 먼 미래에 참조되는 페이지와 현재 할당되는 페이지를 바꾸는 알고리즘
- FIFO (First In First Out)
- 가장 먼저 온 페이지를 교체 영역에 가장 먼저 놓는 방법
- LRU (Least Recently Used)
- 참조가 가장 오래된 페이지 바꿈
- 해시 테이블과 이중연결 리스트로 구현
- NUR (Not Used Recently)
- 시계방향으로 돌면서 0을 찾은순간 해당 프로세스 교체
- LFU (Least Frequently Used)
- 가장 참조 횟수가 적은 페이지를 교체 ( 많이 사용 되지 않은 것 교체)
프로세스와 스레드
- 프로세스 : 컴퓨터에서 실행되고 있는 프로그램, CPU 스케줄링의 대상이 되는 작업
- 스레드 : 프로세스 내 작업의 흐름
프로세스와 컴파일 과정
- 전처리
- 주석 제거 헤더파일 병합
- 컴파일러
- 오류 처리, 코드 최적화 작업 → 어셈블리어로 치환
- 어셈블러
- 목적 코드(object code)로 변환
- 링커
- 실행 파일 생성
- 정적 라이브러리
- 프로그램 빌드 시 라이브러리가 제공하는 모든 코드를 실행 파일에 넣는 방식
- 시스템 환경 등 외부 의존도 낮음
- 코드 중복 등 메모리 효율성이 떨어짐
- 동적 라이브러리
- 프로그램 실행 시 필요할 때만 DLL 이라는 함수 정보를 통해 참조하는 방식
- 메모리 효율성 좋음
- 외부 의존도가 높아짐
프로세스의 상태
- 생성 상태
- 프로세스가 생성된 상태
- fork() , exec() 함수를 통해 생성
- PCB 할당
- fork()
- 부모 프로세스의 주소공간을 그대로 복사 → 새로운 자식 프로세스 생성
- 부모 프로세스의 비동기 작업 등 상속 X
- exec()
- 새롭게 프로세스 생성
- 대기 상태
- 메모리 공간이 충분하면 메모리를 할당 받고 아니면 아닌 상태로 대기함
- CPU 스케줄러로부터 CPU 소유권이 넘어오기를 기다리는 상태
- 대기 중단 상태
- 메모리 부족으로 일시 중단된 상태
- 실행 상태
- CPU 소유권과 메모리를 할당받고 신스트럭션을 수행 중인 상태
- 중단 상태
- 프로세스가 차단된 상태
- I/O 디바이스에 의한 인터럽트로 현상 발생되기도 함
- 일시 중단 상태
- 중단된 상태에서 프로세스가 실행되려고 했지만 메모리 부족으로 일시 중단된 상태
- 종료 상태
- 메모리와 CPU 소유권을 모두 놓고 가는 상태
프로세스의 메모리 구조
동적영역: 스택, 힙
정적영역: 데이터, 코드(Text)
- 스택
- 지역변수, 매개변수, 함수 저장
- 컴파일 시에 크기가 결정됨
- 동적으로 크기가 늘어날 수 있는데, 힙과 스택의 메모리 영역이 겹치면 안되기 때문에 힙과 스택 사이의 공간을 비워둠
- 힙
- 런타임 시 크기가 결정됨
- 데이터
- 전역변수, 정적변수 저장
- 프로그램이 종료되면 사라지는 변수가들어있음
- BSS
- 초기화 되지 않은 변수가 0으로 초기화 되어 저장됨
- Data
- 0이 아닌 다른 값으로 할당된 변수들이 저장됨
- 코드 (Text)
- 소스코드가 들어가는 영역
PCB (Process Control Block)
프로세스에 대한 메타데이터를 저장한 데이터
프로세스가 생성되면 운영체제는 해당 PCB를 생성 → OS가 PCB 관리
커널 스택의 가장 앞부분에서 관리 → 중요한 정보 포함하고 있기 때문 (사용자가 접근 못하게)
- PCB의 구조
- 프로세스 스케줄링 상태
- PID : 프로세스 ID
- 프로세스 권한 : 권한 정보
- 프로그램 카운터 : 프로세스에서 실행해야할 다음 명령어의 주소에 대한 포인터
- CPU 레지스터 : 프로세스를 실행하기 위해 저장해야 할 레지스터에 대한 정보
- CPU 스케줄링 정보 : CPU 스케줄러에 의해 중단된 시간 등에 대한 정보
- 계정 정보 : 프로세스 실행에 사용된 CPU 사용량, 실행한 유저의 정보
- I/O 상태 정보: 프로세스에 할당된 I/O 디바이스 목록
Context Switching
- PCB를 교환하는 과정
- 한 프로세스에 할당된 시간이 끝나거나 인터럽트에 의해 발생
- 어떠한 시점에서 실행되고 있는 프로세스는 단 한개 → 많은 프로세스가 동시에 구동되는 것처럼 보이는 것은 다른 프로세스와의 컨텍스트 스위칭이 아주 빠른 속도로 실행되기 때문
- 비용: 캐시미스
- 프로세스가 가지고 있는 메모리 주소가 그대로 있으면 잘못된 주소 변환이 생기므로 캐시클리어 과정을 겪게 되고 이 떄문에 캐시미스가 발생한다.
- 스레드에서 컨텍스트 스위칭
- 스레드는 스택 영역을 제외한 모든 메모리 공유 → 컨텍스트 스위칭의 경우 비용이 더 적고 시간도 더 적게 걸림
Process Scheduling
- Job Queue
- 프로세스가 시스템에 들어오면 잡 큐에 놓임
- RAM 용량이 적기 때문에 원하는 프로그램을 모두 램으로 옮길 수 없고 램으로 올라올 프로그램을 정하는 큐가 잡 큐
- 하드디스크에 있는 프로그램이 실행되기 위해 메인 메모리의 할당 순서를 기다리는 큐
- Ready Queue
- 실행할 준비가 되어있는 메인 메모리안의 프로세스
- I/O (Device) Queue
- I/O를 하기 위한 여러 장치가 있는데, 각 장치를 기다리는 Queue가 존재
- Long-term scheduler (= job scheduler)
- job queue에 있는 프로세스에 메모리를 할당하여 ready Queue 로 보낼지 결정하는 역할
- 메모리와 디스크 사이의 스케줄링을 담당
- 실행 중인 프로세스의 수 제어
- 프로그램이 RAM으로 올라오는 일은 상대적으로 덜 일어난다 → 시간이 비교적 오래걸림
- Short-term scheduler (= CPU scheduler)
- CPU 와 메모리 사이의 스캐줄링을 담당
- 레디큐에 존재하는 프로세스 중 어떤 프로세스를 CPU에 올릴지 결정
- 스케줄링이 발생하는 시간 짧음
- CPU를 점유하는 순서 정해주는데매우 빠른 시간안에 이루어져야함
멀티 프로세싱
멀티 프로세스를 통해 두 가지 이상의 일을 수행
IPC ( Inter Process Communication)
- Shared memory (공유 메모리)
- 프로세스에 동일한 메모리 블록에 대한 접근 권한이 부여되므로 프로세스가 서로 통신할 수 있도록 공유 버퍼를 생성하는 것
- 기본적으로 각 프로세스의 메모리를 다른 프로세스가 접근할 수 없음 → 공유 메모리를 통해 여러 프로세스가 하나의 메모리를 공유
- 메모리 자체 공유 → 불필요한 데이터 복사의 오버헤드 발생 X → 가장 빠름
- 같은 메모리 영역을 여러 프로세스가 공유 → 동기화 필요
- 하드웨어 관점에서 공유메모리는 CPU가 접근할 수 있는 큰 랜덤 접근 메모리인 RAM을 가리킴
- 파일
- 디스크에 저장된 데이터 또는 파일 서버에서 제공한 데이터
- 소켓
- 동일한 컴퓨터의 다른 프로세스나 네트워크의 다른 컴퓨터로 네트워크 인터페이스를 통해 전송하는 데이터
- TCP / UDP
- 익명 파이프
- 프로세스간에 FIFO 방식으로 읽히는 임시 공간인 파이프를 기반으로 데이터를 주고 받음
- 단방향 방식의 읽기 전용, 쓰기 전용 파이프를 만들어서 작동하는 방식
- 부모, 자식 프로세스 간에만 사용
- 명명된 파이프
- 파이프 서버와 하나 이상의 파이프 클라이언트 간의 통신을 위한 명명된 단방향 또는 이중 파이프
- 클라이언트 / 서버 통신을 위한 별도의 파이프 제공
- 여러 파이프를 동시에 사용 가능
- 컴퓨터의 프로세스끼리 또는 다른 네트워크 상의 컴퓨터와도 통신 가능
- 메시지 큐
- 큐 데이터 구조 형태로 관리하는 것
- 커널의 전역변수 형태 등 커널에서 전역적으로 관리
- 직관적이고 간단
- 간단하게 접근할 수 있는 장점
스레드
프로세스의 실행 가능한 가장 작은 단위
프로세스는 여러 스레드를 가질 수 있음
스레드는 메모리를 공유 (코드, 데이터, 힙) → 한 프로세스 내에 있기 때문 → 직접 소통할 수 있음
→ 훨씬 가볍고 빠름
- TCB (Thread Control Block)
커널 스레드 : 커널이 관리, 할당
유저 스레드: 유저가 관리, 할당
- 멀티 스레딩
- 프로세스 내 작업을 여러 개의 스레드, 멀티 스레드로 처리하는 기법
- 스레드끼리 서로 자원을 공유하기 때문에 효율성이 높음
- 새 프로세스를 생성하는 대신 스레드를 사용하는 웹 서버의 경우 훨씬 적은 리소스를 소비
- → 한 스레드가 중단되어도 다른 스레드는 실행 상태일 수 있음 → 중단되지 않은 빠른 처리 가능
- 장점: 동시성 ( 서로 독립적인 작업들을 작은 단위로 나누고 동시에 실행되는 것처럼 보여주는 것)
- 단점: 한 스레드에 문제 생기면 다른 스레드에도 영향 끼침 → 프로세스에 영향
ds
스레드
프로세스의 실행 가능한 가장 작은 단위
프로세스는 여러 스레드를 가질 수 있음
스레드는 메모리를 공유 (코드, 데이터, 힙) → 한 프로세스 내에 있기 때문 → 직접 소통할 수 있음
→ 훨씬 가볍고 빠름
- TCB (Thread Control Block)
커널 스레드 : 커널이 관리, 할당
유저 스레드: 유저가 관리, 할당
- 멀티 스레딩
- 프로세스 내 작업을 여러 개의 스레드, 멀티 스레드로 처리하는 기법
- 스레드끼리 서로 자원을 공유하기 때문에 효율성이 높음
- 새 프로세스를 생성하는 대신 스레드를 사용하는 웹 서버의 경우 훨씬 적은 리소스를 소비
- → 한 스레드가 중단되어도 다른 스레드는 실행 상태일 수 있음 → 중단되지 않은 빠른 처리 가능
- 장점: 동시성 ( 서로 독립적인 작업들을 작은 단위로 나누고 동시에 실행되는 것처럼 보여주는 것)
- 단점: 한 스레드에 문제 생기면 다른 스레드에도 영향 끼침 → 프로세스에 영향
공유 자원과 임계 영역
- 공유자원 (shared resource)
- 시스템 안에서 각 프로세스, 스레드가 함께 접근할 수 있는 자원이나 변수
- 모니터, 프린터, 메모리, 파일, 데이터 등
- 경쟁 상태 (Race Condition) : 두 개 이상의 프로세스가 동시에 읽거나 쓰는 상황
- 병행성, 병렬성
- → 동시 접근 시도 → 접근의 타이밍이나 순서 등이 결과에 영향
- 시스템 안에서 각 프로세스, 스레드가 함께 접근할 수 있는 자원이나 변수
- 임계 영역 (critical section)
- 둘 이상의 프로세스, 스레드가 공유 자원에 접근할 때 순서 등의 이유로 결과가 달라지는 코드 영역
- 해결방법
- 뮤텍스
- 세마포어
- 모니터
- 조건 만족
- 한정 대기( 특정 프로세스가 영원히 임계 영역에 들어가지 못하면 안됨),
- 뮤텍스
- 프로세스나 스레드가 공유 자원을 lock() 을 통해 잠근 설정하고 사용한 후에는 unlock() 을 통해 잠금을 해제하는 객체
- 하드웨어적
- 세마포어
- 일반화된 뮤텍스
- wait (P 함수), signal (V 함수) 로 공유 자원에 대한 접근을 처리
- wait : 자신의 차례가 올 때까지 기다리는 함수
- signal : 다음 프로세스로 순서를 넘겨주는 함수
- 프로세스나 스레드가 공유자원에 접근 → 세마포어에서 wait() 작업 수행→ 프로세스나 스레드가 공유 자원을 해제 → 세마포어에서 signal() 작업 수행
- 조건 변수 없음
- 프로세스나 스레드가 세마포어 값을 수정할 때 다른 프로세스나 스레드는 동시에 세마포어 값을 수정할 수 없음
- 바이너리 세마포어
- 0 과 1 의 두 가지 값만 가질 수 있음
- 뮤텍스와 차이점
- 뮤텍스 : 잠금을 기반으로 상호배제가 일어나는 ‘잠금 메커니즘’
- 세마포어: 신호를 기반으로 상호배제가 일어나는 ‘신호 매커니즘’
- 카운팅 세마포어
- 여러개의 값을 가질 수 있는 세마포어
- 여러 자원에 대한 접근 제어
- 일반화된 뮤텍스
- 모니터
- 둘 이상의 스레드나 프로세스가 공유 자원에 안전하게 접근할 수 있도록 공유 자원을 숨기고 해당 접근에 대해 인터페이스만 제공
- 구현 쉬움
- 상호배제 자동
- 세마포어 에서는 상호 배제를 명시적으로 구현해야함
교착상태 (DeadLock)
두 개 이상의 프로세스들이 서로가 가진 자원을 기다리며 중단된 상태
- 교착 상태의 원인
- 상호 배제: 한 프로세스가 자원을 독점하고 있으며 다른 프로세스들은 접근이 불가능
- 점유 대기: 특정 프로세스가 점유한 자원을 다른 프로세스가 요청하는 상태
- 비선점: 다른 프로세스의 자원을 강제적으로 가져올 수 없음
- 환형 대기: 프로세스 A는 프로세스 B의 자원을 요구, 프로세스 B는 프로세스 A 자원을 요구하는 등 서로가 서로의 자원을 요구하는 상황
- 교착 상태 해결 방법
- 자원을 할당할 때 애초에 조건이 성립되지 않도록 설계
- 교착 상태 가능성이 없을 때만 자원 할당되며, 프로세스당 요청할 자원들의 최대치를 통해 자원 할당 가능 여부를 파악하는 은행원 알고리즘 사용
- 은행원 알고리즘: 총 자원의 양과 현재 할당한 자원의 양을 기준으로 안정 또는 불안정 상태로 나누고 안정 상태로 가도록 자원을 할당하는 알고리즘
- 교착 상태가 발생하면 사이클이 있는지 찾아보고 이에 관련된 프로세스를 한개씩 지움
- 교착 상태는 매우 드물게 일어남 → 이를 처리하는 비용이 더 커서 데드락이 발생하면 사용자가 작업을 종료함
CPU 스케줄링 알고리즘
- CPU 스케줄링
- 레디큐에 있는 프로세스(스레드)를 골라서 CPU 에 할당해 주는 행동
- 목표: CPU 이용률 높게, 주어진 시간에 많은 일, 레디큐에 있는 프로세스는 적게, ,응답시간은 짧게 설정하는 것
비선점형 방식
프로세스가 스스로 CPU 소유권을 포기
강제로 프로세스를 중지하지 않음 → 컨텍스트 스위칭으로 인한 부하가 적음
- FCFS ( First Come, First Served)
- 가장 먼저 온 것을 가장 먼저 처리
- 길게 수행되는 프로세스 때문에 레디큐에서 오래 기다리는 현상(convoy effect) 발생
- SJF ( Shortest Job First)
- 실생 시간이 가장 짧은 프로세스를 가장 먼저 실행하는 알고리즘
- 긴 시간을 가진 프로세스가 실행되지 않는 현상 (starvation) 발생
- 평균 대기 시간이 가장 짧은
- 실제로는 실행 시간을 알 수 없기 때문에 과거의 실행했던 시간을 토대로 추측해서 사용
- Priority Scheduling (우선순위)
- 우선순위가 가장 높은 프로세스에게 CPU를 할당하는 스케줄링
- 비선점형 방식
- 더 높은 프로세스가 도착하면 레디큐의 헤드에 넣음
- 선점형 방식
- 더 높은 프로세스가 도착하면 실행중인 프로세스를 멈추가 CPU 선점
- starvation
- 무기한 봉쇄 ( 실행준비는 되어있으나 CPU를 사용못하는 프로세스를 CPU가 무기한 대기하는 상태발생)
선점형 방식
지금 사용하고 있는 프로세스를 알고리즘에 의해 중단시키고 강제로 다른 프로세스에 CPU 소유권을 할당하는 방식
- Round Robin 라운드로빈
- 우선순위 스케줄링의 일종
- 동일한 할당 시간을 주고 그 시간안에 끝나지 않으면 다시 레디큐에 넣어버림
- SRF
- 중간에 더 짧은 작업이 들어오면 수행하던 프로세스를 중지하고 해당 프로세스를 수행함
- 다단계 큐
- 우선순위에 따른 레디큐를 여러개 사용 → 큐마다 라운드로빈이나 FCFS 등 다른 스케줄링 알고리즘 적용
- 큐 간의 프로세스 이동이 안됨 → 스케줄링 부담 적음 , 유연성 떨어짐
데드락(교착상태) 의 발생과 해결 방법
- 데드락(교착상태)
- 두 개 이상의 프로세스 혹은 스레드가 서로가 가진 리소스를 기다리는 상태
- 데드락의 네가지 조건
- Mutual exclusion
- 리소스를 공유해서 사용할 수 없다.
- Mutual exclusion