Researcher to Developer

01. 프로세스와 스케쥴러 2 본문

코딩/Basic

01. 프로세스와 스케쥴러 2

Probe29 2020. 12. 10. 21:44

#스케쥴러 알고리즘

#선점형 스케쥴러
하나의 프로세스가 다른 프로세스 대신에 프로세서(CPU)를 차지할 수 있음
- 시 분할 시스템
중단이라는 과정에 고려해야 할 것이 많앗기 때문에 후반에 등장하게 됨


#비선점형 스케쥴러
하나의 프로세스가 끝나지 않으면 다른 프로세스는(CPU)를 사용할 수 없음
blocking(wait)되거나 end해야 가능
스케쥴러가 제어할 수 없어!
초반에 등장했음.


#선점형과 비선점형 스케쥴러 차이
비선점형 : 프로세스가 자발적으로 blocking 상태로 들어가거나, 실행이
끝났을 때만, 다른 프로세스를 running! 교체 가능
응답시간이 길어질 수 있음

선점형 : 프로세스 running 중에 스케줄러가 이를 중단시키고, 다른
프로세스로 교체가능!
응답시간이 빠르고 OS가 사용자가 원하는 최적의 스케쥴링을 할 수 있음!

 

OS.xlsx → Preemptive

 

 

#스케쥴러 구분(정책, policy)
FIFO(FCFS), SJF(프로세스 실행시간이 짧은 애들 먼저 실행시킬꺼야)
, Priority-based(우선 순위가 높은 프로세스를 먼저 실행시킬꺼야)는 
어떤 프로세스를 먼저 실행시킬지에 대한 알고리즘 → 비선점형 스케쥴러에 가까움

Round robin은 시분할 시스템을 위한 기본 알고리즘 → 선점형 스케쥴러 기반


#최신 기술은 여러 가지 복합해서 스케줄링 알고리즘을 짠다.


#랙? 마우스/키보드 반응이 느린 경우??
스케쥴러가 해결해야하는 이슈!, 다양하고 복잡한 스케쥴링 알고리즘 필요
프로그램이 CPU를 혼자 너무 많이 차지하는 경우!

리눅스 스케쥴러 - O(1), CFS와 같은 다양한 방식으로 변경시도 중
프로세스 타입을 알게 되면 우선순위를 매긴다든지.
인터렉티브(=쉘), IO, CPU 중심 프로세스 등으로 미리 구분할 수 있다면 보다 개선한 스케쥴링이 가능함



#인터럽트??
어느 한 순간 CPU가 실행하는 명령은 하나! 다른 장치와 어떻게 커뮤니케이션을 할까요?

CPU가 프로그램을 실행하고 있을 때, 입출력 하드웨어 등의 장치나 또는 예외상황(이벤트)이 발생하여
처리가 필요할 경우에 CPU에 알려서 처리하는 기술

- 이벤트 발생에서 처리 과정으로 넘어가게 해주는 것 인터럽트(Interrupt)

어떤 녀석이 프로세스나 스케쥴러에 파일 읽기가 다 끝낫어요!! 이거를 알려줘야
Block state에서 ready state에서 대기하다가 CPU로 넘어가서 Running을 할꺼잖아??
그것을 누가 어떻게 알려줄건데?? 


#인터럽트가 필요한 이유 *이벤트에 대한 처리를 위해 OS 내부에서 진행함!
선점형 스케쥴러 구현에서 필요하다!
프로세스 running 중에 스케쥴러가 이를 중단시키고, 다른 프로세스로 교체하기 위해, 현재
프로세스 실행을 중단시킴

IO Devcie와의 커뮤니케이션
저장매체에서 데이터 처리 완료 시, block state에서 ready state로 처리를 할 때 와 같이 프로세스를 깨워야할때 필요. 


예외 상황 핸들링
CPU가 프로그램을 실행하고 있을 때, 입출력 하드웨어 등의 장치나 또는 예외상황이나 문제가 발생할 경우,
CPU가 해당 처리를 할 수 있도록 CPU에 알려줘야함!

예외상황의 예)
Code중에 1/0 (0으로 나누기) 같은 연산 CPU가 처리하자마자 문제가 생깁니다!
0으로 나누는 것은 불가능하다고 함! 그러면 다음 프로세스 진행을 해야하는데 
(구현에 따라)프로세스나, OS나, 스케쥴러에 알려줘서 프로세스를 Kill 하게 한다.




#인터럽트 처리 예

CPU가 프로그램을 실행하고 있을 때,
  입출력 하드웨어 등의 장치 이슈 발생
    파일 처리가 끝났다는 것을 운영체제에 알려주기
    운영체제는 해당 프로세스를 block state에서 실행 대기(ready) 상태로 프로세스 상태 변경하기

또는 예외 상황이 발생
   0으로 나누는 계산(오류!)가 발생해서, 예외 발생을 운영체제에 알려주기
   운영체제가 해당 프로세스 실행 중지/에러 표시해서 사용자가 알게끔 해준다.


#이벤트와 인터럽트
  인터럽트는 일종의 이벤트로 불림
  이벤트에 맞게 OS가 처리하도록 구현되어 있다.


#주요 인터럽트
  1. 계산하는 코드에서 0으로 나누는 코드 실행 시(Divide-by-Zero Interrupt)

#include <stdio.h>

int main()
{
        printf("Hello World|n");
        int data;
        int divider = 0;
        data = 1 / divider;   # 1을 0으로 나누는 이 부분에서 인터럽트 발생
        return 0;
}


  2. 타이머 인터럽트(타이머 인터럽트를 발생시키는 컴퓨터 내 별도의 칩이 존재)
   선점형 스케쥴러를 위해 필요
하드웨어로 부터 일정 시간마다 타이머 인터럽트를 운영체제 알려줌!

100ms = 1/10 초마다 프로세스 변경하겠다! 라고 하면 어느 순간 변수 값이 10이 되는 순간
스케줄러가 프로세스 변경을 하겠죠?
CPU에 프로세스 실행이 될 텐데 어느 시점에 스케쥴러가 동작해서 프로세스 변경을 한다!
=선점형 스케쥴러




  3. IO 인터럽트(입출력) 
프린터, 키보드, 마우스, 저장매체등을
사용하면 그 명령을 처리해야 하는 인터럽트가 필요!



#인터럽트 종류
- 내부 인터럽트(Software interrupt)
 주로 프로그램 내부에서 예외 상황(잘못된 명령 이나 데이터 사용)시 발생
   0으로 나눴을 때
   사용자 모드에서 허용되지 않은 명령 또는 공간 접근 시
* ex) 리눅스 경우에 0GB 부터 4GB 전체를 하나의 프로세스 공간이라고 정의를 해놓음
0~3GB 까지는 사용자 모드 커널 모드(슈퍼 관리자) 3~4GB 까지만 접근
C언어 포인터가 에러가 나서
사용자 모드에서 프로세스가 커널 모드에서만 접근할 수 있는 공간에 접근한다??
그러면 인터럽트로 처리한다.


   계산 결과가 Overflow/Underflow 날 때
변수가 표현하는 범위를 벗어 날 때

    
- 외부 인터럽트(Hardware Interrupt) 
주로 하드웨어에서 발생되는 이벤트(프로그램 외부)
타이머 이벤트
전원 이상
IO 관련 이벤트


 

#인터럽트 전반적인 구조
#시스템 콜 인터럽트
- 시스템 콜도 내부적으로는 인터럽트 방식으로 처리를 함
- 시스템 콜 실행을 위해서는 강제로 코드에 인터럽트 명령을 넣어 CPU에게 실행시켜야 한다.

- 시스템 콜 실제 코드(시스템 콜은 각각의 번호가 있음)
readonly - RDONLY(C언어)
함수는 인자 값이 있을 수 있음
eax 레지스터에 시스템 콜 번호를 넣고,
ebx 레지스터에는 시스템 콜에 해당하는 인자값을 넣고,
소프트웨어 인터럽트 명령을 호출하면서 0x80값을 넘겨줌

mov eax, 1 여기서 1은 시스템 콜 번호
mov ebx, 0 여기서 0은 인자
int 0x80 // 소프트웨어 인터럽트 명령 여기서 int는 CPU op code(Intel 계열), 0x80은 Interrupt 번호(시스템 콜 0x80 으로 정함)
다른 인터럽트와는 다르게 강제로 시킬 수 있음

#인터럽트와 시스템 (고급)
시스템 콜 인터럽트 명령을 호출하면서 0x80 값을 넘겨줌
1. CPU는 사용자 모드를 커널 모드로 바꿔줌
2. IDT(Interrupt Descriptor Table, 인터럽트 번호에 맞는 특정한 주소(코드)가 매칭이 되어있음)에서
3. 0x80(시스템 콜의 인터럽트 번호)에 해당하는 주소(함수)를 찾아서 실행함
4. system_call()함수에서 eax(시스템 콜 번호에 해당하는 함수를 call)로 부터 시스템 콜 번호를 찾아서 해당 번호에 맞는 시스템 콜 함수로 이동
커널 모드에서 해당 시스템 콜 함수 실행 후, 다시 커널 모드에서 사용자 모드로 변경하고, 다시 해당 프로세스 다음 코드 진행


#사용자/커널 모드와 프로세스, 인터럽트
- 프로세스가 사용자 모드에서 실행을 하다가 운영 체제가 코드가 필요할 때 시스템 콜을 통해
커널 모드에 들어갈 수 있다.
- 타이머 인터럽트가 주로 프로세스 스케줄러에서 쓰인다.
- 타이머 인터럽트가 계속 발생되다가 어느 스케줄러가 정한 횟수에 다다르면 타이머 인터럽트에 따라서
스케줄러 코드가 프로세스를 바꿔서 다른 프로세스를 실행시키고 하는 과정은 커널모드에서 작업된다.
- 시스템 콜이 실행될 때 뿐만 아니라 타이머 인터럽트가 걸릴 때마다도 커널모드로 바뀐다는 것!


#인터럽트와 IDT(Interrupt Descriptor Table)
- 인터럽트는 미리 정의되어 각각 번호(이벤트 마다)와 실행 코드를 가리키는 주소가 IDT에 기록되어 있음
- 이벤트 번호에 따른 함수가 저장되어 있는 실행 코드를 주소를 가리킴
- IDT는 컴퓨터 부팅 시 운영체제가 기록한다.
- 인터럽트가 걸리면 CPU에서는 무조건 IDT에 가서 인터럽트(이벤트) 번호에 맞는 주소의 코드를 실행하게된다!
- 운영체제 내부 코드에 있다 → 커널모드/커널영역(특정한 메모리 공간)

1. 항상 인터럽트 발생 시, IDT 확인
2. 시스템 콜 인터럽트 명령은 0x80 번호가 미리 정의
3. 인터럽트 0x80에 해당하는 운영체제 코드는 system_call()이라는 함수
4. 즉 IDT에는 0x80 → system_call()와 같은 주소 정보가 기록되어 있음 

리눅스의 예
0 ~ 31 : 예외 상황 인터럽트 (내부/ 소프트웨어 인터럽트, 일부는 정의 안된 채로 남겨져 있음)
32 ~ 47 : 하드웨어 인터럽트 (주변장치 종류/갯수에 따라 변경 가능)
128 : 시스템 콜


#인터럽트와 프로세스의 관계
1. 프로세스 실행 중 인터럽트 발생하면
2. 현 프로세스 실행 중단하고 
커널 모드로 변경 → 커널 모드에서 IDT에서 해당하는 함수 실행(운영체제 내부에서)
→ 함수에 맞는 코드 실행 → 다시 사용자 모드
3. 현 프로세스 재실행



#인터럽트와 스케줄러의 관계 - ex. 선점형 스케줄러 구현
- 선점형 스케줄러는 수시로 타이머 인터럽트 발생하면 그것을 카운트해서 처리하는 것이 일반적
 → 운영체제가 타이머 인터럽트 발생 횟수를 기억해서 5번 타이머 인터럽트를 발생하면, 현재
프로세스를 다른 프로세스로 바꿔준다.

















'코딩 > Basic' 카테고리의 다른 글

01. 프로세스와 스케쥴러 4  (0) 2020.12.14
01. 프로세스와 스케쥴러 3  (0) 2020.12.13
01. 프로세스와 스케쥴러 1  (0) 2020.12.10
Operation System - OS.운영체제 2  (0) 2020.12.09
Operation System - OS.운영체제  (0) 2020.12.08