* 복습

cpu 스케줄링의 매커니즘 : ready 큐에 있는 프로세스중 누구한테 cpu를 줄지 정하는 것.
(크게 두가지 이슈가 있다)


1. cpu burst에 들어온 수많은 프로세스들중 누구한테 줄까?
2. cpu를 프로그램한테 줬으면 I/O를 하러 나갈때까지 계속 줄꺼냐? 아니면 중간에 뺏을꺼냐?

 

즉, 누구한테 줄것인가? 일단 줬으면 중간에 뺏어 오게 할 수 있게 할 것인가.
(공평도 필요하지만 효율적으로 하기위한 매커니즘)


* CPU 스케줄링 알고리즘

 

 

# 알고리즘들을 크게 두가지로 나누어 본다면,

 1) NONPreemtive 한 스케줄링 : 강제로 cpu를 빼앗지 않는 방법 (일단 cpu한번 주면 자진반납할때 까지 cpu보장해주는 방법- 비선점형)

 2) Preemtive 한 스케줄링 : 언제든지 뺏어올 수 있는 방법 (선점형, 요즘은 이걸 많이씀)

 

 

* CPU 스케줄링 성능 척도

 

 

 

# 성능척도를 크게 두가지로 생각해 볼수 있다.
 1) 시스템 입장에서의 성능 척도
  : CPU 하나를 가지고 최대한 일을 많이 시키면 좋은것(파란색 2개)
 2) 프로그램 입장에서의 성능 척도
  : 내가(프로세스) CPU를 빨리 얻어서 빨리 끈나면 좋은것, 그래서 시간과 관련이 있는 3가지를 고려(빨간색 3개)


# 척도 소개


 (처음 2개는 사장 입장)
 - CPU utilization : 전체 시간중에서 cpu가 놀지 않고 일한 시간.
 - Througput : 주어진 시간 동안에 몇개의 작업을 처리 하였느냐

 

 (밑에 3개는 고객입장(빨리 서비스 받고 싶다.))
 - Turnaround time : cpu를 쓰러 들어와서 다쓰고 나갈때 까지의 시간. (waiting time + cpu이용시간)
 - Waiting time : cpu를 쓰고자 ready큐에서 기다리는 시간
 - Response time : ready큐에 들어와서 cpu쓰겠다고 들어와서 처음으로 cpu를 얻기까지 걸린 시간.

 

cf> waiting time과 response time의 차이를 구분해보자면, preemtive(선점형)인 경우, cpu를 계속해서 돌려쓰게 되는데
1) waiting time : 기다리는거 모두 합한 값.
2) response time : 제일 처음 기다린 시간.
3) turnaround time : waiting time + 실행 시간

 

???) 시간을 왜 굳이 3개씩이나 나누지?
: 응답시간을 둔 이유는 time sharing 환경에서는 처음으로 cpu를 얻는 시간이 사용자 응답과 관련해서 굉장히 중요한 시간의 개념이다. 그래서 반환시간도 있고 대기시간도 있지만 응답시간을 별도로 둬서 이야기 하는 이유이다!


* FCFS
 : 먼저오면 먼저 처리 (NoonPreemtive)

 

 

 

# NoonPreemtive한 스케줄링이다. 중간에 시간이 많이 걸리는게 있다면 비효율적이다.

 

 

 

# 앞에 경우와 비교해보면 평균 waiting time이 짧아진것을 볼 수 있다.

# Convoy effect : 긴 프로세스가 먼저 도착해서 짧은 프로세스들이 지나치게 많은 시간을 기다리는 효과를 의미. (부정적 효과)

 

 

SJF
 : 수행시간이 짧은게 먼저 처리

 

 

 

# Average waiting time이 최소화 되는 방법.

 

# SJF 알고리즘도 두가지 방법으로 나누어서 생각해 볼수 있다.

1) NoonPreemtive 한 방법
2) Preemtive한 방법 : cpu를 줬다 하더라고 남은 수행시간이 더 짧은 애가 오면 cpu를 빼앗긴다.(SRTF 라고도 부른다)

 

 

# 두가지 예를 봐보자

 

1) NoonPreemtive version.


 

 


2) Preemtive version.


 

 

 

# Preemtive 버전이 더 짧다는것을 알수 있다. (더 좋다.)

 

 

???) 그러나 두가지 문제점이 있다.

 

1) starvation(기아현상) : SJF는 수행시간이 짧은거를 선호 하기 때문에, 수행시간이 긴 프로세스는 영원히 서비스를 못 받을 수도 있다.

2) 매번 cpu사용 시간을 미리 알수 없다는게 문제이다. 그럼 SJF는 실제로 적용 못하나요? => 정확히는 알수 없지만, 과거의 사례(과거의 CPU burst time)을 통해서 추정한다

 

 

 

# 다음 cpu burst time 예측

 : 점화식을 해석해 보면 과거일수록 반영하는 가중치가 줄어든다.

 

 

 

 

 

 

 

 

 

* Priority Scheduling 
 : 우선순위가 높은 프로세스한테 cpu할당

 

 

 

# Priority Scheduling 알고리즘도 두가지 방법으로 나누어서 생각해 볼수 있다.

1) NoonPreemtive 한 방법
2) Preemtive한 방법 : cpu를 줬다 하더라고 남은 수행시간이 더 짧은 애가 오면 cpu를 빼앗긴다.(SRTF 라고도 부른다)

cf> 작은 숫자가 우선순위가 높다.

 

# Aging : 아무리 우선순위가 낮더라 하더라도, 시간이 지나게 되면서 우선순위를 조금씩 높여주자(starvation의 해결책!)

 

* Round Robin
: 가장 현대적인 스케줄링 알고리즘, 여태 우리가 배웠던 시스템이 RR이다.

 

 

 

# RR의 장점 : cpu 응답시간이 빨라진다. (누구든지 조금만 기다리면 cpu를 맛볼수 있다.)
(n-1)q 만 기다리면 내 차례가 돌아온다. (q라는 퀀텀을 짧게 잡아줄수록 내 차례가 빨리 다가온다.)

 

#
1) q를 너무 크게 잡으면 : FCFS
2) q를 너무 짧게 잡으면 : context switch 오버헤드가 커진다.(시스템 전체 성능이 나빠질수 있다.)
 => 즉, 너무 크거나 짧게 q를 잡으면 성능이 나빠진다.

 

 

# 할당 시간(q)이 20 인경우의 예제

 

 

 

# RR의 장점 : Response time이 줄어든다!!

'cs > os' 카테고리의 다른 글

#6-1. Process Synchronization  (0) 2018.01.11
#5-3. CPU SCHEDULING  (0) 2018.01.09
#5. CPU SCHEDULING  (0) 2018.01.04
#4. Process Management  (0) 2018.01.02
#3-3. Thread  (0) 2017.12.29

#5 CPU SCHEDULING

 


 

* cpu and I/O Bursts in Program Execution




# cpu bursts : cpu만 실행 되는곳

  I/o bursts : I/O만 실행 되는곳


# 프로그램의 종류에 따라 cpu burts와 I/O bursts의 빈도가 달라진다.

cf> 주로 사람이 만지는 프로그램은 I/O bursts가 높아지고,

    과학 계산용 프로그램은 cpu bursts가 높다.


* cpu-bursts time의 분포

 

 


# 그래프 분석 : job의 종류가 섞여있다.

# cpu bursts가 짧은 경우(빨간색 네모) : 중간에 i/o가 많이 끼어드는 경우가 많았다. => I/O bound job

  cpu bursts가 긴 경우(파란색 네모)   : 중간에 i/o가 많이 끼어들지 않았다. => cpu bound job


!!!) 이렇듯 여러 종류의 job(=process)이 섞여 있기 때문에 cpu 스케줄링이 필요하다.

 

  - cpu 스케줄링의 중요한 역할 중에 하나는!!!

  : I/O bound job 처럼 사람하고 interaction 하는 job 에게 cpu를 우선적으로 주는것. (효율성을 위해!!)

    즉, interactive 한 job들을 오래 기다리게 하지 않는것


* 프로세스의 특성 분류

 

 


* CPU Scheduler & Dispatcher

 

 


# CPU 스케줄러 : 누구한테 CPU를 줄지를 정함.

 ???) CPU 스케줄러는 HW or SW?

     : CPU 스케줄러는 os kernel에 있는 스케줄링 해주는 code이다.


# Dispatcher : cpu를 누구한테 줄지 결정했으면, 그 친구에게 cpu를 넘겨주는 역할을 함.

  cf> 마찬가지로 kernel에 있는 code.


!!!과정))

 - 방금전에 cpu에서 돌아가던 process의 context를 save하고, 

 - 새로 cpu를 넘겨주는 process의 context를 펼쳐놓는다.

 - cpu 안에다가 register 값 세팅 해놓고,

 - 그런다음에 cpu를 넘겨준다.


# cpu 스케줄링이 필요한 경우 

 1. I/O 작업처럼 오래 걸리는 작업을 하는 경우

 2. cpu를 계속 쓰고 싶은데 timer interrupt가 발생해서 빼앗는 경우

 3. 오래 걸리는 작업이 끈낫을때 (device controller가 interrupt를 걸어서 ready상태로 만들어 줌.)

 4. 

'cs > os' 카테고리의 다른 글

#5-3. CPU SCHEDULING  (0) 2018.01.09
#5-2. CPU SCHEDULING  (1) 2018.01.08
#4. Process Management  (0) 2018.01.02
#3-3. Thread  (0) 2017.12.29
#3-2. Process  (0) 2017.12.27

#4. Process Management

 

 

* 프로세스의 생성
: 부모 프로세스가 자식 프로세스를 생성.
 cf> 생성하는 방법 : 복제 생성(메모리(code, data, stack), cpu문맥(pc)을 copy.)

 

 v. 계층구조 : 트리구조

 v. 프로세스는 자원을 필요함(실행이 되려면)
  - os로부터 받는다.
  - 부모와 자원을 공유한다.
   (공유하지 않는 모델도 있고, 일부만 공유하는 모델도 있다.)

 
  #보통 일반적인 경우는 자원을 공유하지 않고, 자식 프로세스가 생성되자마자 서로 cpu를 더 차지 하기 위한 경쟁관계가 된다.

 

 v. 수행(Excution)
  - 부모와 자식은 공존하며 수행되는 모델
  - 자식이 종료(terminate)될 때까지 부모가 기다리는(wait)모델

 

  # 부모와 자식이 공존하며 수행되는 모델이 있고, 자식을 생성하고 종료 될때까지 기다리는 모델이 두가지가 있다. 이 것들을 자세히 알아보자.

  # 메모리를 아끼기 위해 공유할수 있는거는 copy하지 않고 공유하는 효율적인것들도 있다.

 

 vv. 주소공간(address space)
  - 자식은 부모의 공간을 복사함(복제 생성)-------1단계(fork)
  - 자식은 그 공간에 새로운 프로그램을 올림------2단계(exec)

 

 vv. 유닉스의 예
  - fork() 시스템 콜이 새로운 프로세스 생성
   .부모를 그대로 복사 (os data except PID + binary)
   .주소 공간 할당

 

  - fork 다음에 이어지는 exec() 시스템 콜을 통해 새로운 프로그램을 메모리에 올림.

 

# 일단 fork()로 생성한다음에 복제해서 exec()를 사용해서 필요한거만 덮어 씌운다.

 

* 프로세스 종료

 v. 프로세스가 마지막 명령을 수행한 후 os에게 이를 알려줌(exit)
  - 자식이 부모에게 output data를 보냄(via wait).
    # 자식이 항상 부모보다 먼저 죽는다!!


  - 프로세스의 각종 자원들이 os에게 반납됨

# 자발적으로 프로세스가 종료되는것 : exit
    비 자발적으로 종료 되는것        : abort

 

 v. 부모 프로세스가 자식의 수행을 종료시킴(abort)
  - 자식이 할당 자원의 한계치를 넘어섬
  - 자식에게 할당된 task가 더 이상 필요하지 않음
  - 부모가 종료(wait)하는 경우
   . os는 부모 프로세스가 종요하는 경우 자식이 더 이상 수행되도록 두지 않는다.
   . 단계적인 종료

 

# 자식이 사치(자원한계치 이상)부리거나,

(일시키려고 자식을 생성했기 때문)할 일이 없거나,

 부모가 먼저 죽게 되는

경우에 자식을 죽인다.

 

 

* fork() 시스템 콜

 

 


# fork를 사용해서 프로세스를 만드는 코드
# fork() 빨간 부분은 시스템콜 부분이다.

 

# 문제점 : fork를 통해 복제를 할 경우 문제점
1) 복제를 해놨더니 지가 원본이라고 주장한다. 부모 프로세스를 자식 취급을 하면, 굉장히 혼란스러운 상황이 발생.
2) 부모와 똑같은 제어흐름을 따라가야 될거 같다....

해결책)) 
 1.부모와 자식을 구분을 해준다.
   어떻게?)) return value를 다르게 한다.
             자식은 0, 부모는 양수가 된다. (pid 설명.)

 2. 부모와 자식 프로세스가 다른일을 하게 해주는 system call
   : exec()

 

* exec() 시스템 콜
 : 어떤 프로그램을 완전히 새로운 프로세스로 태어나게 해주는 역할을 한다.


 

 

 

# execlp는 일종의 함수인데, 이것이 exec 시스템콜을 하게 된다.
# exec을 하게되면 fork와 달리 main 처음부터 실행을 하게 된다.

 

 

* wait()
 : 자식이 종료될때까지 기다리는 시스템 콜

 

 


ex> 리눅스 커널도 wait() 시스템콜이 사용된다. (콘솔 기다리는 거 상상하자.)


* exit()
 : 프로그램을 종료할때 실행하는 시스템 콜.

 

 

 

# 보통 자발적으로 종료될때 실행이 된다, 코드가 없어도(code에 exit()가 없어도) 마지막 코드 읽어주고 exit()가 실행됨.


* 프로세스와 관련한 시스템 콜(정리)

 

 - fork() : 부모 프로세스 복제 생성하는 것.
 - exec() : 완전히 새로운 프로그램으로 덮어 씌우는 것
 - wait() : 자식이 종료될때 까지 기다리는 것
 - exit() : 모든 자원을 반납하고 부모 프로세스한테 죽는다고 알리는 것.

 

 


* 프로세스 간 협력

 

 

 

# 프로세스는 원칙적으로 독립적이다.(부모가 자식을 죽이는것 말고는 프로세스들이 서롤 영향을 미치지 못한다.)

# process 협력: 프로세스간의 정보 교환
  정보를 교환하는 방법 => IPC

 

 

* Message Passing
 : 커널을 통해서 메시지를 passing 할수 있다.

 

# 메세지 패싱에는 또 2가지 방법이 있다.
: 상대 메시지를 받아볼 프로세스 이름을 명시 하느냐 안하느냐에 따라 2가지로 나뉨. (직접 통신 / 간접 통신)


# 2가지 방법으로 나누지만, 어쨋껀 메세지를 전달하려면 os의 kernel을 통해 전달해야 하는건 똑같다.

why?)) 프로세스 끼리는 메세지를 전달하는게 불가능 하기 때문에! 


# 간접 메시지는 아무나 꺼내갈수 있게 할수 있다! (상황에 따라 맞게 설계하도록 하자.)

 

 

* 일부 주소 공간을 공유하는 IPC
 : 아래 그림은 물리적인 공간

 

 

# 원칙적으로 process들은 독자적인 주소공간을 각자 가지고 있지만 일부 process들은 주소 공간을 공유한다.

# 공유된 주소공간은 접근을 바로 할 수 있다.

# shared 공간을 쓰려면 kernel한테 mapping(인제 shared 공간을 사용하겠다)을 해놓고, 그때부터는 사용자 프로세스끼리는 한쪽에서 쓰면 다른쪽에서 볼수있다.
 즉, shared memory 처음 하는것은 kernel의 도움을 받지만, 일단 kernel이 한번 해주면 그 이후는 가능하다. 
 
** 단, shared memory를 쓰려면 두 프로세스는 굉장히 신뢰할만한 프로세스여야 한다.

cf> 쓰레드들간의 협력은 주소공간을 같이 쓰기 때문에 유용하다.

 

 

 

'cs > os' 카테고리의 다른 글

#5-2. CPU SCHEDULING  (1) 2018.01.08
#5. CPU SCHEDULING  (0) 2018.01.04
#3-3. Thread  (0) 2017.12.29
#3-2. Process  (0) 2017.12.27
#3-1. Process  (0) 2017.12.27

#3-3. Thread

 


* PCB


 

 

# 프로세스마다 하나의 pcb가 만들어져서 os가 관리 하게 된다.

# 쓰레드는 프로세스 마다 가지고 있는 정보 중에서, cpu수행과 관련있는 정보만 가지고 있게 된다. => pc, register

 

 

** 쓰레드가 별도로 가지고 있는 정보들과 공유하는것들을 사진으로 알아보도록 하자.

 

 

 

 

# 쓰레드는 주소공간에서 data, code는 공유하고 stack 부분만 별도로 가지고 있게 된다.
# 쓰레드는 pcb에서 pc, register 정보만 별도록 가지고 있게 된다.

 

 

* Single and Multithread Process

 

 

#공유된 파란색 부분과 독자적으로 가지는 빨간색 부분!

 

 

* 쓰레드의 장점!!


--- cpu가 1개 일때도 얻는 장점! ---

 

1. 응답성(빠르다)

 

# 예)) 내가 웹브라우저를 띄워 놓고 어떤 포털사이드의 홈페이지 주소를 치게 되면 제일먼저 html 문서가 날라오게 된다.

그 문서를 web browser 화면에 display 하려고 봤더니 그 안에는 여러가지 이미지가 있다. 그거를 웹 브라우저가 해석을 해서 이미지들을 다시 웹서버에 요청을 한다. 그래서 그 이미지들이 도착을 하면 여러 다른 텍스트들도 집어 넣고 중간중간 이미지도 넣어가지고 하나의 웹 페이지를 완성해서 사용자에게 보여주게 된다.
 근데 그러한 과정에서 제일 먼저 html 문서를 읽어온 다음에 그 안에 있는 이미지들을 다시 웹서버에게 요청을 한다. 그러면 그게 오래 걸리는 작업이기 때문에 프로세스를 block 시킨다. 그럼 사용자 입장에서는 답답하다. 왜나하면 프로세스가 block 이 되어서 화면에 띄우는 걸 못한다.

이렇게 하지않고 웹 브라우저를 여러개의 쓰레드를 사용해서 만들게 되면 하나의 쓰레드만 block되고 다른 쓰레드가 일을 하게 된다. 그래서 더 빨리 결과를 볼 수 있게 된다.

 

-> 일종의 비동기식 입출력이 된다.

 

2. 자원 공유 (Resource Sharing)

 

# 하나의 프로세스를 만들고 그 안에 cpu 수행 단위만 여러개를 두게 되면, code, data 각종 자원은 쓰레드들이 공유 하기때문에 자원을 효율적으로 쓸수 있게 된다.

 

3. 경제성 (응답성과는 약간 다른 '빠르다'의 의미)

 

# 프로세스 내부에서 쓰레드 간의 cpu 스위칭이 일어나는 것은 굉장히 간단하다.

why)) 동일한 주소공간을 사용하기 때문에

<비교 : 문맥교환은 오버헤드가 크다.>
=> 같은일을 하는 작업이라면 프로세스를 여러개 만드는것보다 프로세스 안에 쓰레드를 여러개 두는것이 효율적이다.

 

--- cpu가 여러개 일때 얻는 장점! ---

 

4. 병렬성

 

# 프로세스는 하나지만 쓰레드가 여러개 있다면, 각각의 쓰레드들이 cpu를 점유해서 연산속도가 올라간다.
 => 결과를 더 빨리 얻을 수 있다. (멀티 프로세서 환경에서 효울적)

 

 

* 쓰레드 구현 방법

 

1. 커널 쓰레드 : 쓰레드가 여러개 있다는 사실을 운영체제 커널이 알고 있다. 그래서 하나의 쓰레드에서 다른 쓰레드로 cpu가 넘어가는것도 커널이 cpu 스케줄링 하듯이 넘겨주게 된다.

 

2. 유저 쓰레드 : 라이브러리르 통해서 지원된다. 프로세스 안에 여러 쓰레드가 있다는것은 os는 모르고 유저 프로그램이 관리 하는것.

 

# 커널의 지원을 받으면 커널 쓰레드.
  사용자 수준에서 쓰레드를 구현하게 되면 유저 레벨 쓰레드

 

3. real- time 쓰레드

 

 

'cs > os' 카테고리의 다른 글

#5. CPU SCHEDULING  (0) 2018.01.04
#4. Process Management  (0) 2018.01.02
#3-2. Process  (0) 2017.12.27
#3-1. Process  (0) 2017.12.27
#2-2. System Structure & Program Execution  (0) 2017.12.25

#3-2. Process

 

???) 동기식 입출력과 비동기식 입출력의 차이점.

- 동기식 : 입출력 진행되는 동안에 프로세스가 아무일도 하지 않고 기다리는 것.

- 비동기식 : 입출력이 진행되는 동안에 그 프로세스가 cpu를 잡아서 instruction을 실행을 하는것.

 


* Thread
 : 프로세스 내부에 cpu 수행 단위

 

 

 

# pc가 code 어느부분을 가리키게 된다.

 

# Thread 라는건 프로세스 하나에서 공유할수 있는건 최대한 공유,
 1. 메모리 주소공간 (data, code)
 2. 프로세스 상태
 3. 프로세스가 사용하는 각종 자원들

 

# 별도로 가지고 있는것. (점선으로 되어있는것)
 1. cpu 관련된것들(PC, register)
 2. 주소공간의 (stack)

 

* Thread 정리 (light weight process)
 : cpu를 수행하는 단위

 

 v. Thread의 구성 (독립적으로 가지고 있는 것)
  - Program Counter
  - register set
  - stack space

 v. Thread가 동료 thread와 공유하는 부분 (=task)
  - code section
  - data section
  - OS resources

 v. 전통적인 개념의 heavy weight process는 하나의 thread를 가지고 있는 task로 볼 수 있다. 
 
* 쓰레드를 사용하면 어떤 장점이 있나?

 

 - 응답시간이 빨라진다.
 : 다중 스레도로 구성된 task 구조에서는 하나의 서버 스레드가 blocked(waiting) 상태인 동아넹도 동일한 task 내의 다른 스레드가 실행 (running)되어 빠른 처리를 할 수 있다.

 

 - 동일한 일을 수행하는 다중 스레드가 협력하여 높은 처리율과 성능 향상을 얻을 수 있다.

 

 - 스레드를 사용하면 병렬성을 높일 수 있다.

 
 ex> 웹 브라우저에서 naver를 본다면, network을 통해서 web page를 읽어오는 작업이 I/O 작업이된다.

     만약 멀티 스레드가 아니라면 이 작업중에 사용자는 아무것도 할 수 없게 되어 답답한게 된다.

'cs > os' 카테고리의 다른 글

#4. Process Management  (0) 2018.01.02
#3-3. Thread  (0) 2017.12.29
#3-1. Process  (0) 2017.12.27
#2-2. System Structure & Program Execution  (0) 2017.12.25
#2-1. System Structure & Program Execution  (0) 2017.12.24

#3-1. Process

cf> process = (한 마디로) 실행중인 프로그램


 

 


* process`s context
 : 이 프로세스가 어디까지 와 있는가 => PC가 필요.
   (즉, 현재 상태 규명)

 v. cpu 수행 상태를 나타내는 하드웨어 문맥 (cpu)
   - Program Counter
   - 각종 register
 v. 프로세스의 주소 공간   (memory)
   - code, data, stack
 v. 프로세스 관련 커널 자료 구조  (kernel)
   - PCB(Process control Block)
   - Kernel stack


cf> 프로세스는 생성이 되면 독자적인 주소공간을 생성한다.


* Process State

- 프로세스는 상태가 변경되며 수행된다.
  => 크게 3가지로 구분!! cpu를 잡고 있거나, 기다리거나, 무언가 오래걸리는 작업을 하고 있거나
 
 v. Running : cpu를 잡고 instruction을 수행중인 상태
 v. Ready : cpu를 기다리는 상태(메모리 등 다른 조건은 모두 만족)
 (즉, cpu만 얻으면 instruction을 실행할수 있는 상태)
 v. Blocked(wait, sleep)
  - cpu를 주어도 당장 instruction을 수행할 수 없는 상태
  - Process 자신이 요청한 event(예:I/O)가 즉시 만족되지 않아
    이를 기다리는 상태
  - (예)디스크에서 file을 읽어와야 하는 경우

 

(경우에 따라 2가지 추가)
 v. New : 프로세스가 생성중인 상태
 v. Terminate : 수행(excution)이 끝난 상태

 

# Ready상태에 있는 프로세스들이 번갈아가며 cpu를 잡았다 놓았다 하면서 time sharing을 구현하고 있다.
# Blocked 상태에 있는 프로세스의 예))
  virtual 공간(주소 공간)에 있는 것들중 메모리에 올라가 있지 않고 disk(swap area)에 내려가 있는 것.

 

 

<프로세스 생태도>

  (이 글의 마지막에 상태도는 suspended 상태 때문에 약간 변하게 된다. )

 

# ready 상태는 최소한의 메모리를 가지고 있다.(당장 instruction실행하는데 필요한 부분들이 메모리에 있다.)

# running 에서는 나가는것이 3가지가 있다.
1. 자진해서 cpu를 내놓는 경우.
  (I/O같은 그런 이벤트 처리를 위해)
2. cpu를 계속 쓰고 싶은데 time sharing을 위해 시간이 다되어서 timer interrupt가 들어와서 ready 상태로 돌아가는 경우.

3. 할일 다해서 끈나는 경우.

 이 상태 변화를 컴퓨터 시스템 입장에서 알기 쉽게 그려놓은것.

 

 

# process는 큐에 들어가서 줄을 서서 자기 차례를 기다린다. (실은 기다린 순서대로 가는것이 아니라 우선순위가 있다.)

 

 

 

 

 

 


# kernel이 Data자료구조를 만들어 놓고, 이런것들을 통제한다.

 

 

* PCB 
 : 커널이 프로세스를 관리하기 위해서 PCB를 둔다.

 

 

# 구성요소(4가지)를 잘보자.

 

 

** 문맥교환 (굉장히 중요한 개념!!)
 : cpu를 게속 이용하는것이 아니라 뺏겼다가 다시 사용한다.
 뺏겼다가 다시 사용할때, 뺏긴 시점의 문맥을 기억했다가 다시 사용하는것이 포인트!

 

 


# 문맥 교환시 필요한 작업.
 : 프로세스가 cpu를 빼앗길때
   pc, register정보(왼쪽 노란색), memory map(아래 초록색) 정보를
   저장해둔다.
   why)) 뺏긴 시점의 문맥을 기억하기 위해!!

 

<문맥교환 그림 설명>


# cpu 제어권 넘어가는걸 설명하는 그림.
# A -> kernel -> A :(다시 A로 오는건 문맥교환x)
  A -> kernel -> B :(문맥교환!!)
# timer 인터럽트 or 오래걸리는 작업(ex> I/O) 의 인터럽트에서는 문맥교환이 일어난다!!
# 문맥교환에는 수행정보등 context의 일부를 PCB에 save 해야해서 cach memory flush(오버헤드)가 발생함.

 

 

* 프로세스를 스케줄링하기 위한 큐

 

 

# job queue 에는 ready queue, device queue 에 들어있는 프로세스들도 들어 있다!!
# But!! ready queue <-> device queue 이다.

 


 
** 실제 프로그램에서 큐가 어떻게 관리되는지 그림으로 알아보자.

 

 

# 1번째가 ready 큐 이고,
  밑에 4개가 device 큐 이다.

 

 

*프로세스 스케줄링 큐의 모습

 

 


# 마지막에 인터럽트가 발생했을떼 ready 상태로 넘어가는거 처럼 그려졌는데 정확하게는 ready상태로 넘어가는게 아니다.(틀린 그림)

 

 

* 스케줄러
 : 순서를 정해주는 것

 - Short-term scheduler
  : 굉장히 짧은 시간 단위로 스케줄이 이루어 진다.
  : 다음번에 어떤 프로세스한테 cpu를 줄지를 결정

 

 - Long-term scheduler
  : 메모리를 어떤 프로세스한테 줄지를 결정.
  : 프로세스가 new 상태에서 메모리에 올라가는것이 허락이 되야 ready 상태가 될수 있다. 그 허락을 결정하는것이 이 스케줄러.
  : degree of MultiProgramming을 제어(memeory에 몇개를 올려 놓을지를 결정하는 것.) -> 중요!!
  : 현재에는 안쓰임.(무조건 ready 상태로 들어감)

  ???)그러면 현재에는 degree of MultiProgramming을 어떻게 제어 하는가? => Medium-term Scheduler!!

 

 - Medium-term Scheduler(swapper)
  : 일단 memory에 다 올려 놓고, memory에 너무 많은 프로세스가 올라가 있으면 필요없는것을 골라 통째로 쫒아냄!!

 


 

# 프로세스의 상태 3가지에, 중기 스케줄러 때문에 추가된 상태가 Suspended 상태이다!
 => 메모리를 통재로 빼앗긴 프로세스들의 상태를 나타냄.
# blocked 와 suspended를 구분하자!
 blocked는 자신의 오래걸리는 작업이 끈나면 다시 ready가 될 수 있지만,
 suspended는 외부에서 허락을 받아야 한다

cf> 사람이 ctrl+z 를 눌러서 프로세스를 중지 시켰을때도 suspended 상태가 된다. 사람이 프로세스를 재개시키면 다시 위의 상태로 돌아갈 수 있다.

 

 

 

** 프로세스 상태도 (최종)

 

 

# running을 두가지로 나누었다.


 

=====================================================================================================

 

※ 추가 개념

 

# pc 또한 register 이다.

# pc는 code부분을 카리킨다.

 

# (사진 설명)

: (code, data, stack)은 가상 주소 공간 이므로,

  pc는 Memory(물리적 공간)에 있는 code를 가리킨다. 

 

# cpu에 관한 문맥은 2가지가 있는데,

 1) pc : 다음 실행할 주소를 가리킨다.

 2) registers : 이 정보로 인해서 다음에 어디를 실행해야 할지 알 수 있다.

'cs > os' 카테고리의 다른 글

#3-3. Thread  (0) 2017.12.29
#3-2. Process  (0) 2017.12.27
#2-2. System Structure & Program Execution  (0) 2017.12.25
#2-1. System Structure & Program Execution  (0) 2017.12.24
# Thread  (0) 2017.12.17

#2-2. System Structure & Program Execution


복습))

 instruction은 보통 4byte 이다.

 그렇기 때문에 순차적일때 pc(program counter)는 4가 증가한다.

 But, 항상 일정한건 아니다!(if, continue etc)

 

 

* 동기식 입출력(synchronous I/O)

 : I/O요청 후 입출력 작업이 완료된 후에야 제어가 사용자 프로그램으로 넘어감.

  (즉, 완료가 되어야 다음일을 할 수 있다.)


* 비동기식 입출력(asynchronous I/O)

 : I/O가 시작된 후 입출력 작업이 끝나기를 기다리지 않고 제어가 사용자 프로그램에 즉시 넘어감.

  (안끈나도 다음작업이 가능하다.)


cf> I/O는 커널을 통해서만 사용이 가능하다.


 

* DMA (Direct Memory Access)

 : 메모리에 접근하는 장치

 

 v. 작은일들은 바로 cpu에 interrupt 거는게 아니라 DMA를 거친다.

(byte 단위가 아니라 buffer에다 저장해뒀다가 블록 단위로 전송)

즉, CPU가 효율적으로 일할 수 있게 해주는것.



* 저장장치 계층 구조

 

 

 

v. 위로 올라갈 수록 

  - 스피드 빠르고

  - 비싸고(그래서 용량이 적다.)

  - 휘발성이다.

 v. cpu가 직접 접근할수 있는 것이 Primary구간(초록)


cf> cpu가 직접 접근하기 위해선 byte 단위로 접근이 가능해야하는데,

 DRAM 메모리 같은경우 byte단위로 주소를 매겨서 접근할수 있다.

 반대로, 하드디스크 경우는 섹터 단위로 주소를 매긴다.


 - 캐시메모리 : 속도 차이를 완충해주는 역할

그러나 메모리가 main memory보다 작아서 당장 필요한거만 저장해서 쓴다. 이것을 caching 이라고 부른다.(보통 캐싱은 재사용을 목적으로 한다.)

 

 - register : 이곳을 통해 instruction을 읽어들인다.


** 프로그램이 어떻게해서 실행이 되는가?

 


실행파일 형태로 하드디스크에 저장 되있고, 실행시키게 되면 메모리에 올라가서 프로세스가 된다. 그렇게 실행이된다.

정확하게는 물리적인 메모리에 바로 올라가는것이 아니라 virtual memory를 거치게 된다.


모든 프로그램이 독자적인 주소 공간(virtual memory)을 가지고 있다.


이것이 통째로 물리적인 메모리에 올려놓는게 아니라 당장 필요한것은 물리적인 메모리에 올려놓고, 당장필요하지 않은것은 swap area에 내려 놓는다.



* 메모리 주소변환 계층

 논리적인 메모리 주소 -> 물리적인 주소로 변환되는것

 (이부분은 뒤에서 자세히..)

 


 

* 커널 주소 공간의 내용

 

뒤에 자세히 하겠다.. 생김새 정도만 살펴 보자


 

cf> 어떤 프로그램이던 함수형 언어로 짜여 있다.

 

 


 

* 함수

커널함수(시스템 콜) Vs 사용자정의 함수, 라이브러리 함수

-------------------------------------------------------------------

커널안에 있다               사용자 프로세스 코드 영역에 들어있다


=> 즉, 사용자 프로세스가 커널함수를 사용하고 싶다면 스스템콜을 사용하여 interrupt가 발생시켜 cpu제어권을 os에게 넘겨보내어 실행을 하게 된다.

 

[실행 예시]

 



'cs > os' 카테고리의 다른 글

#3-3. Thread  (0) 2017.12.29
#3-2. Process  (0) 2017.12.27
#3-1. Process  (0) 2017.12.27
#2-1. System Structure & Program Execution  (0) 2017.12.24
# Thread  (0) 2017.12.17

#2-1. System Structure & Program Execution

: 운영체제를 설명하기 앞서 하드웨어적인 동작을 설명.


 



컴퓨터란? : cpu + memory


memory = cpu의 작업공간


* cpu는 매 클럭 사이클마다 instruction(기계어)를 하나씩 읽어서 실행을 하게된다.

  => cpu의 운명.


- register : cpu안에는 memory보다 더 빠른 메모리 저장 공간이 있다

- mode bit : 지금 cpu에서 사용되는것이 운영체제인지 or 사용자명령인지 구분해주는 것.


 => 1 : 사용자 프로그램 수행

      0 : 모니터모드. 커널모드 (os가 cpu사용)

 v. 보안을 해칠수 있는 중요 명령어는 모니터 모드에서만 실행가능.

 v. interrupt 발생시, mode bit 0으로 set.

 v. 사용자 프로그램에 cpu넘기기 전에 mode bit 1로 set.

 

    => 보안을 목적으로 instruction set을 나누어 놓았다.



* timer

: 특정프로그램이 cpu를 독점하는것을 막는것 (무한루프 방지)

 v. 매 클럭 틱 때마다 1씩 감소

 v. 셋팅해놓은 시간이 끈나면 ‌interrupt를 넣어준다.

 v. cpu는 intertupt line을 체크한다.

 

=> 즉, cpu의 time sharing 구현을 위한 하드웨어!!



* I/O device


- device controller : I/O device는 각각 작은 cpu역할을 하는 컨트롤러가 있다.


cf> device driver : 각 장치에 맞게 접근할 수 있게 해주는 SW모듈.


- local buffer : device controller들도 작은 메모리 공간이 필요한데, 이곳은 로컬 버퍼라고 부른다.

 v. 실제 I/O는 device와 로컬 버퍼 사이에서 일어남.

 v. I/O가 끈나면 컨트롤러가 interrupt로 cpu에 그 사실을 알림.



* DMA controller :  이러다 보면 cpu가 너무 interrupt를 너무 많이 당하게 된다. 그래서 이것이 필요하다. (직접 메모리 접근 가능)


=> 즉, DMA는 cpu를 효율적으로 사용하기 위해 필요한것.


* memory controller : DMA와 CPU의 교통정리를 해주는 컨트롤러.


* 모든 입출력 명령은 특권 명령이다.

- 시스템콜 : 사용자 프로그램이 os의 커널함수를 호출하는것.

 : 일반 함수 호출과는 조금 다르다. 

 프로그램이 interrupt를 걸면서(mode bit=0) 시스템콜을 하게된다.

 이 인터럽트를 Trap 이라고 한다.

 

   v. Exception   : 프로그램 오류를 범한 경우.

   v. System call : 프로그램이 커널함수를 호출하는 경우.

   v. trap이 걸리면 cpu가 os로 넘어가게 된다.

cf> 일반 함수 호출은 memory 주소를 바꾸는 것으로 가능하다.


???) 

Q. I/O를 요청하는 interrupt : SW 인터럽트(trap)

   I/O가 끈난다면     : HW 인터럽트를 이용해서 끈난것을 알려준다.


 

=> 현대의 os는 interrupt에 의해서 구동된다.

'cs > os' 카테고리의 다른 글

#3-3. Thread  (0) 2017.12.29
#3-2. Process  (0) 2017.12.27
#3-1. Process  (0) 2017.12.27
#2-2. System Structure & Program Execution  (0) 2017.12.25
# Thread  (0) 2017.12.17

● PROCESS : 실행중인 프로그램

       ------------------> 자원 + 공간(*) + 쓰레드(**) 로 이뤄짐.


  * 자원        : 공간(호출스택)의 크기에 따라 호출할 수 있는 쓰레드의 수가 결정된다.

  ** 쓰레드    : 쓰레드의 갯수에 따라 싱글 쓰레드와 멀티 쓰레드로(***) 나뉜다. 


  *** < 멀티 쓰레드의 장점 >

                                  

1. cpu의 활용률 향상                                     

2. 자원을 보다 효율적으로 사용                         

3. 사용자에 대한 응답성 향상                           

4. 작업이 분리 되기 때문에 코드가 간결해진다.

=> 쓰레드와 사용자 요청이 1:1 대응이 되도록 프로그래밍 해야 한다.


< 멀티 쓰레드의 단점 > --> 이 부분에 대해선 뒤에서 자세히 다루자.


1. 동기화 문제

2. 교착상태

=> 여러 쓰레드가 자원을 공유하면서 작업을 하기 때문에 발생.


cf> 프로세스의 성능이 쓰레드의 개수와 비례하진 않는다.



● 쓰레드 구현 방법

 

1. Thread 클래스 상속

   -> But, Thread클래스를 상속받으면 다른 클래스를 상속 받을 수 없다.


2. Runnable 인터페이스 구현.

   -> 이 방법을 주로 

 ex>

1
2
3
class MyThread implements Runable {
    public void run() { /* 작업 내용 */ }
}
cs


● 한번 사용한 쓰레드는 재 사용될 수 없다. (즉, 한번 start() 한 것을 또 start()할 수 없다.)

 


● 예시를 통해 호출스택 내부를 살펴보도록 하자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class ThreadEx3 {
 
    public static void main(String[] args) throws Exception {
        MyThreadEx3_1 t1 = new MyThreadEx3_1();
        t1.run();
    }
 
}
 
class MyThreadEx3_1 extends Thread {
    public void run() {
        throwException();
    }
    
    public void throwException() {
        try {
            throw new Exception();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
cs


실행결과

java.lang.Exception

at GodBell.MyThreadEx3_1.throwException(ThreadEx3.java:19)

at GodBell.MyThreadEx3_1.run(ThreadEx3.java:14)                        

at GodBell.ThreadEx3.main(ThreadEx3.java:7)

 

 

: 이 예제는 고의적으로 예외를 발생시켜서 호출스택의 내용을 확인할 수 있도록 했다.

 (start() 메서드가 아니라 run()메서드 이기 때문에 main()메서드가 호출스택에 포함되어 있음을 확인할 수 있다.)

 

● start VS run

 

start() : 쓰레드 실행 (새로운 호출 스택 생성)

run()  : 단순히 클래스에 속한 메서드 하나를 호출

 

cf> start()가 호출된 쓰레드는 바로 실행되는것이 아니고, 일단 대기상태에 있다가 스케줄러가 정한 순서에 의해 실행.

     실행중인 쓰레드가 하나도 없을 때 program은 종료된다. 

 

 

 

 

● 싱글 쓰레드 VS 멀티 쓰레드

 

 - cpu 만을 사용하는 계산 작업이라면 오히려 싱글 쓰레드가 더 빠르다.

   why)) 스위칭 때문!! (다음에 실행하는 위치(PC)등의 정보를 저장하고 읽어오는 시간이 소요된다.)

 

 - 프린트기 사용이나 다른 입력장치와 함께 사용할때에는 멀티쓰레드가 더 좋다. 

 

 

● 쓰레드는 우선순위 속성을 가지고 있다.

 

 - 우선순위 (1 ~ 10) : 클수록 우선순위가 높다.

 - 절대적이 아니라 상대적인 개념.

ex> 1, 2    ==    9, 10    

     (두 경우 모두 우선순위가 1차이 만큼 우선순위 속성을 가지고 있다.)

 - main의 쓰레드의 우선순위는 '5'이므로 main 내의 생성한 쓰레드는 우선순위 '5'를 갖게된다.

 

 

● 쓰레드 그룹

 

 - 그룹 : 폴더개념이라고 생각하자.

 - 보안상의 이유로 만들어졌다. (자신이 속한 그룹이거나, 하위그룹 쓰레드는 변경 가능 하지만 다른 그룹의 쓰레드는 내용 변경 불가!)

 - 모든 쓰레드는 그룹에 포함되어야 한다.

 

 - ThreadGroup(String name)을 사용해서 그룹 생성 가능.

 - 쓰레드 그룹에 포함시키려면 "생성자"를 이용해야 한다.

   if> 생성자를 안썻다면?

: 자신을 생성한 쓰레드와 같은 그룹에 속하게 된다.

 

=> 즉, 우리가 생성한 모든 쓰레드는 모두 main 쓰레드 그룹에 속하게 된다.

 

 

~641 PAGE 부터 이어집니다.... (데몬 쓰레드 부터 시작) 



'cs > os' 카테고리의 다른 글

#3-3. Thread  (0) 2017.12.29
#3-2. Process  (0) 2017.12.27
#3-1. Process  (0) 2017.12.27
#2-2. System Structure & Program Execution  (0) 2017.12.25
#2-1. System Structure & Program Execution  (0) 2017.12.24

+ Recent posts