쓰레드(Threads)와 동기화(Synchronization)

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
경성대학교 양희재 교수님 수업 영상을 듣고 정리하였습니다.


쓰레드 (Thread)

프로그램 내부의 흐름, 맥

class Test {
  public static void main(Sting[] args) {
    int n = 0;
    int m = 6;

    System.out.println(n+m);

    while (n < m)
    n++;

    System.out.println("Bye");
  }
}

하나의 프로그램은 하나의 맥이 있고 이러한 맥을 쓰레드라고 한다.

Multithreads

  • 다중 쓰레드(Multithreads)
    • 한 프로그램에 2개 이상의 맥
    • 맥이 빠른 시간 간격으로 스위칭 된다 => 여러 맥이 동시에 실행되는 것처럼 보인다. (concurrent vs simultaneous)
    • 현재의 모든 프로그램들은 다 다중쓰레드를 지원한다.

동시에 돌 수 있는 이유는 맥이 빠른시간으로 스위칭 되기 때문이다.
그래서 실제로 같이 하고 있는 것처럼 보이지만 사실 CPU는 하나이기 때문에 우리는 하나만 사용하고 있다. 우리는 일반적으로 concurrent!

  • 예: Web breoser
    • 화면 출력하는 쓰데르 + 데이터 읽어오는 쓰레드
  • 예: Word Processor
    • 화면 출력하는 쓰레드 + 키보드 입력 받는 쓰레드 + 철자/문법 오류 확인 쓰레드
  • 예: 음악 연주기, 동영상 플레이어, Eclipse IDE…

실제 context switching 되는 단위는 process단위가 아니라 thread단위이다!

Thread vs Process

  • 한 프로세스에는 기본 1개의 쓰레드: 단일 쓰레드(single thread) 프로그램
  • 한 프로세스에 여러개의 쓰레드: 다중 쓰레드 (multi-thread) 프로그램

  • 쓰레드 구조
    • 하나의 프로그램에서 맥이 여러개다.
    • 프로세스의 메모리 공간을 공유한다 (code, data를 쓰레드가 서로 공유)
    • 프로세스의 자원공유(한 쓰레드 안에서 file, io 등을 공유)
    • 비공유: 개별적인 PC(program counter), SP(stack pointer), Registers, stack
      • CPU가 p1에 있는 각각의 쓰레드가 가지고 있는 PC값은 다를 것이다. 그래서 스위칭 될때마다 각자가 가리키고 있는 값이다르니 이 값들은 공유하지 않는다.
      • 스택은 리턴값 혹은 파라미터 값을 저장하기 위해 사용되는데, 서로간에 호출하는 메소드가 다 다를수가 있다.

하나의 프로그램은 코드, 데이터, 스택으로 구성되는데 쓰레드가 코드, 데이터는 공유를 하지만 이때 스택은 따로 가지고 있다.

  • 프로세스의 스위칭 vs 쓰레드의 스위칭
    현대의 모든 운영체제는 context switching 단위가 쓰레드간의 단위이다.

예: 자바 쓰레드

  • 맥 만들기
    • java.lang.Thread
      • 자바에서는 쓰레드가 객체로 이루어져있기 때문에, 쓰레드라는 객체를 만들어줘야함
    • 쓰레드가 가지고 있는 주요 메소드
      • public void(run): 새로운 맥이 흐르는 곳
      • void(start): 쓰레드 시작 요청
      • void(join): 쓰레드가 마치기를 기다림
      • static void(sleep): 쓰레드 잠자기 / 멈추도록

java.lang.Thread

  • Thread.run()

쓰레드가 시작되면 run()메소드가 실행된다(run()메소드를 치환한다)
run()안에서 안에서 새로운 맥이 실행되기 때문에 run()을 치환해야 하고, 치환하려면 쓰레드 클래스에 하위 클래스를 만들어서 치환한다.

class MyThread extends Thread{
  public void run() { // 치환(override)
    // 코드
    while (True) {
      System.out.println("B");
      try {
      Thread.sleep(100);
      } catch (InterruptedException e) ()
    }
  }
}
class Test {
  public static void main(String[] args) {
    MyThread th = new MyThread()
    th.start();
    while (True) {
      System.out.println("A");
      try {
      Thread.sleep(100);
      } catch (InterruptedException e) ()
    }
  }
}
  • 모든 프로그램은 처음부터 1개의 쓰레드는 갖고 있다(main)
  • 2개의 쓰레드: main + MyThread

해당 프로그램이 시작되면 main함수가 먼저 시작할것이다. main함수의 MyThread가 실행되면서 while문의 무한루프가 돌면서 B가 계속해서 찍혀나갈 것이고 그와 동시에 main함수의 while문이 무한루프를 돌면서 A를 계속해서 찍어낼 것이다. 컴파일해보면 A와 B가 섞여서 찍힐 것이다.

프로세스 동기화(Process Synchronization)

더 정확한 표현은 Thread Synchronization이다.
서로간 영향을 주고받는 데이터들간에 데이터의 일관성이 유지될 수 있도록 해주는 것이 동기화이다.

보통 컴퓨터 메모리 안의 프로세스들은 독립적이지 않고 협조하는 관계이다. 즉, 다른 프로세스에게 영향을 주거나 영향을 받는다. 대부분 공통된 자원(메인메모리)을 서로 접근하려고 하다보니 그런것이다. 하나의 메인메모리에 프로세스들이 많으니 어떤 방식으로든 영향을 주고받으니 그럴수록 프로세스 동기화의 개념이 중요해지고 있다.

  • Processes
    • Independent vs Cooperating
    • Cooperating process: one that can affect or be affected by other processes executed in the system(그 시스템 내에서 실행되고 있는 다른 프로세스에 대해서 프로세스 간 영향을 주든지 영향을 받든지하는 프로세스)
    • 프로세스 간 통신: 전자우편, 파일 전송(서로 공유하며 데이터 통신을 함)
    • 프로세스간 자원 공유: 메모리 상의 자료들, 데이터베이스 등(데이터를 공유하기에 서로에게 영향을 줌)
    • 명절 기자표 예약, 대학 온라인 수강신청, 실시간 주식거래
  • Process Synchronization
    • Concurrent access to shared data may result in data inconsistency
    • Orderly execution of cooperating processes so that data consistency is maintained -> 공유 데이터에 동시에 접근하면 데이터의 비일관성을 초래한다.
      -> 서로간 영향을 주고받는 데이터들간에 데이터의 일관성이 유지될 수 있도록 해주는 것이 동기화이다.
  • ex: BankAccount Problem(은행계좌문제)
    • 부모님은 은행계좌에 입금, 자녀는 출금
    • 입금(deposit)과 출금(withdraw)은 독립적으로 일어난다.
class BankAccount {
  int balance;
  void deposit(int n) {
    balance = balance + n;
  }
  void withdraw(int n ){
    balance = balance + n;
  }
  int getBalance() {
    return balance;
  }
}
class Parent extends Thread {
  BankAccount b;
  Parent(BankAccount b) {
    this.b = b;
  }
  public void run() {
    for (int i=0; i<1000;, i++)
      b.deposit(1000);
      System.out.println("+");
  }
}
class Child extends Thread {
  BankAccount b;
  Child(BankAccount b) {
    this.b = b;
  }
  public void run() {
    for (int i=0; i<1000;, i++)
      b.withdraw(1000);
      System.out.println("-");
  }
}
class Test {
  public static void main(String[] args)
  throws InterruptedException {
    BankAccount b = new BankAccount();
    Parent p = new Parent(b);
    Child c = new Child(b);

    p.start();
    c.start();
    p.join();
    c.join();

    System.out.println("balance = " + b.getBalance());
  }
}

잔액은 0원이 나올 것이다.

프로세스 동기화가 안되는 경우의 문제

시간지연에 따라 잘못된 결과를 초래한다.

class BankAccount {
  int balance;
  void deposit(int n) {
    balance = balance + n;
    System.out.println("+");
    balance = temp;
  }
  void withdraw(int n ){
    balance = balance + n;
    System.out.println("-");
    balance = temp;
  }
  int getBalance() {
    return balance;
  }
}
class Parent extends Thread {
  BankAccount b;
  Parent(BankAccount b) {
    this.b = b;
  }
  public void run() {
    for (int i=0; i<1000;, i++)
      b.deposit(1000);
  }
}
class Child extends Thread {
  BankAccount b;
  Child(BankAccount b) {
    this.b = b;
  }
  public void run() {
    for (int i=0; i<1000;, i++)
      b.withdraw(1000);
  }
}
class Test {
  public static void main(String[] args)
  throws InterruptedException {
    BankAccount b = new BankAccount();
    Parent p = new Parent(b);
    Child c = new Child(b);

    p.start();
    c.start();
    p.join();
    c.join();

    System.out.println("balance = " + b.getBalance());
  }
}

시간지연에도 불구하고 결과는 바르게 나와야하는데, 이를 해결해야하는 것을 동기화라고 한다.
-> context switching이 중간에 일어나게 되면 이상한 결과를 초래할 수 있다.
-> 공통변수(common variable, balance)에 대한 동시 업데이트(concurrent update)로 인해 발생!
(즉, 하이레벨 랭귀지는 한줄이지만 로우레벨은 여러줄인데 업데이트 도중에 스위칭이 발생)
-> 해결: 공통변수에 대해 한번에 한 쓰레드만 업데이트 하도록한다! 임계구역 문제 = atomic하게!

임계구역 문제(Critical-Section Problem)

Critical section(임계구간, 치명적인 구간): 이 구간에서 아주 치명적인 오류가 발생할 수 있다.

A system consisting of multiple threads. Each thread has a segment of code, called critical section, in which the thread may be changing common variables, updating a table, writing a file, and so on

여러개의 쓰레드로 구성된 시스템에서 각각의 쓰레드는 어떤 코드의 영역을 가지고 있는데, 그 코드의 영역을 임계구역이라고 한다. 이 임계구역이 되기 위해서는 여러 쓰레드들이 공통의 변수, 테이블, 파일들을 바꾸는 부분 코드를 임계구역이라고 한다.

  • Solution (3개가 모두다 만족되어야 한다.)
    • Mutual exclusive(상호배타): 오류가 일어나지 않으려면 공통 변수에 대한 업데이트는 오직 한 쓰레드만 들어가 있을 때 진행되어야 한다. 즉 Parent가 critical section에 들어가면 그 순간에는 Child가 critical section에 들어가면 안된다.

    • Progress(진행): 진입 결정은 유한 시간 내에 일어나야 한다. 즉 critical section에 누가 들어갈 것인지를 결정하는 것은 유한 시간 내에 일어나야 한다.

    • Bounded waiting(유한대기): 어느 쓰레드라도 유한 시간 내에 일어나야 한다. 기다리는 시간의 한계가 들어가 있다는 것으로 내가 기다리고 있다면 유한 시간 내에 critical section 안으로 들어갈 수 있다.

프로세스/쓰레드 동기화

  • 임계구역 문제 해결
  • 프로세스 실행 순서 제어(원하는대로)
  • Busy wait 등 비효율성 제거

프로세스 관리에서 중요한 것은 결국 프로세스/쓰레드의 동기화이다. 틀린답이 나오지 않도록 os에서 임계구역 문제를 해결해줘야 한다. 그리고 프로세스/쓰레드의 순서를 임의로 제어할 수 있어야 한다.

프로세스 생성과 소멸

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
경성대학교 양희재 교수님 수업 영상을 듣고 정리하였습니다.


프로세스의 생성과 소멸

Process Creation

  • 프로세스는 프로세스에 의해 만들어진다. (init process에 의해)
    • 부모 프로세스(Parent process)
    • 자식 프로세스(Child process)
      • cf. Sibling process
    • 프로세스 트리 (process tree)
  • Process Identified(PID): 프로세스 번호, 중복되지 않음, 그 번호의 프로세스가 죽기전까지는 그 번호를 재할당못함
    • Typically an integer number: 전형적으로 정수형 숫자
    • cf. PPID: 부모의 할당 ID
  • 프로세스 생성
    • fork(): 새로운 프로세스를 생성하는 system call
    • exec(): 만들어진 프로세스로 하여금 실행하도록 하기 위해서 실행파일을 메모리로 가져오기 위해서 복사

ps: process state / ps -a
UID: User ID
PID: Process ID
PPID: Parent Process ID

Process Termination

  • 프로세스 종료
    • exit() system call: 해당 시스템 콜을 호출하면 프로세스가 종료됨
    • 해당 프로세스가 가졌던 모든 자원(메모리, 파일, 입출력 장치 등..)은 OS에게 반환: 이 OS는 이 자원을 필요로 하는 애한테 다시 보내줄 것이다.

CPU Scheduling - FCFS, SJF, Priority, RR, 다중 큐 스케줄링

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
경성대학교 양희재 교수님 수업 영상을 듣고 정리하였습니다.


CPU Scheduling

Ready Queue에서 프로세스들이 CPU의 서비스를 받기 위해 기다리는데, 현재 CPU에서 하고 있는 작업이 끝나게되면 어느 프로세스를 가져올지 결정하는 것

  • Preemptive vs Non-Preemptive (선점 vs 비선점)
    • Preemptive: CPU가 어떤 프로세스를 막 실행하고 있는데, 아직 끝나지도 않았고 IO를 만나지도 않았음에도 강제로 쫓아내고 새로운게 들어갈 수 있게하는 스케줄링 방식
    • Non-Preemptive: 이미 한 프로세스가 진행중이면 절대 스케줄링이 일어나지 않는 것
  • Scheduling criteria(스케줄링 척도)
    • CPU Utilization(CPU 이용률, %): CPU가 얼마나 놀지 않고 일하는가?
    • Throughput(처리율, Jobs/ms): 시간당 몇개의 작업을 처리하는가?
    • Turnaround time(반환시간, m/s): 작업이 들어온 시간부터 끝날때까지의 시간
    • Waiting time(대기시간, m/s): cpu 서비스를 받기 위해 얼마나 기다렸는가?
    • Response time(응답시간): 처음 응답이 나올때까지의 시간, interactive computer에서 중요

CPU Scheduling Algorithm

  • First-Come, First-Served(FCFS): 먼저 온놈을 먼저 작업한다.
  • Shortest-Job_First(SJF): 작업시간이 짧은 놈을 먼저 작업한다.
    • Shortest Remaining-Time-First
  • Priority: 우선순위가 높은 놈을 먼저 작업한다.
  • Round-Robin(RR): 빙빙 돌면서 순서대로 작업한다.
  • Multilevel Queue : Queue를 여러개 둔다.
  • Multilevel Feedback Queue

First-Come, First-Served(FCFS)

  • simple & fair: 먼저 온 놈을 먼저 작업한다. 제일 간단하고 공평한 방법이다. 그러나 정말 좋은 방법인가?
    • 꼭 좋은 성능을 나타내는 것은 아니다.
  • example: Find Average Waiting Time
    • AWT = (0+24+27)/3 = 17 msec cf.3 msec!

3개의 프로세스가 거의 동시에 Ready Queue에 도착했다고 해보자.

  • Gantt Chart
Process Burst Time(CPU 이용시간)
P1 24
P2 3
P3 3
  • Convoy Effect(호위효과): cpu 실행시간을 많이 쓰는애가 딱 앞에 있으면 나머지 애들이 뒤를 따라다니며 기다리고 있는 모습-> FCFS 의 단점
  • Non-Preemptive Scheduling: p1이 끝날때까지 나머지는 못들어감.

Shortest-Job_First(SJF)

실행시간이 가장 짧은 작업을 가장 먼저 실행함으로써 짧게 끝나는 프로세스를 앞장세워야 전체 대기시간이 줄어들게 함

  • Example : QWT = (3+16+9+0)/4 = 7msec
    • ch. 10.25msec(FCFS)
  • Provably optimal!
    • 대기시간을 줄이는 측면에서는 가장 좋은 방법!
  • Not realistic, prediction may be needed
    • 비현실적이다. 실제로 이 프로세스가 얼마를 사용할지를 우리는 알수가 없다. 실제 돌려보기 전까지는 전혀 알수가 없다. 그래서 가장 이상적이지만 비현실적이다. 실제로 사용하기에는 예측을 할 수 밖에 없다. 예측하기 위해서는 os가 그동안 cpu를 사용했던 시간들을 다 정리해놓고 예측을 하는 것이긴 이 예측을 하기 위해서는 overhead가 많은것이고 그 만큼의 계산도 많이 들게된다.
Process Burst Time(CPU 이용시간)
P1 6
P2 8
P3 7
P4 3
  • Preemptive or Non-Preemptive
  • cf. Shortest-Remaining-Time-First(최소잔여시간 우선): 남아있는 시간이 얼마나 짧은가가 우선시가 된다.

  • Example
    • Preemptive: AWT =(9+0+15+2)/4 = 6.5msec
    • Non-Preemptive: 7.75 msec
Process Arrival-Time Burst Time(CPU 이용시간)
P1 0 8
P2 1 4
P3 2 9
P4 3 5

Priority

  • typically an integer number
    • Low number represents high priority in general(Unix/Linux)
    • 우선순위, 컴퓨터 프로그램에서는 정수값으로 나타내는데 대부분의 운영체제에서는 숫자가 작을수록 우선순위가 높아진다.
  • Example
    • AWT = 8.2 msec
Process Burst Time(CPU 이용시간) Priority
P1 10 3
P2 1 1
P3 2 4
P4 1 5
P5 5 2
  • 우선순위는 어떻게 정하는가?
    • Internal: time limit, memory requirement, i/o to CPU burst…
      • 내부: 짧을수록, 메모리를 적게 사용할수록, io시간이 길고 CPU 사용시간이 적을수록..
    • External: amount of funds being paid, political factors…
      • 외부: 돈을 많이 낸쪽을 먼저, 정치적인 요소일수록..
  • Preemptive or Non-Preemptive
    • 둘다 만들 수 있음
  • Problem
    • Indefinite blocking: starvation(기아)
      • 한 프로세스가 끝나고 그 다음 우선순위가 작동을 하게 되는데, 이 와중에도 외부에서는 계속해서 작업들이 들어올것이다. 그런데 아무리 오래 기다리고 있다고 하더라고 새로 들어오는 애들이 더 우선순위가 높다면 이전에 있던 애들 중에서도 계속해서 메모리에 올라가지 못하는 애들이 있을 것이다.
    • Solution: aging
      • 오래 기다릴수록 우선순위를 조금씩 올려주는 것. 레디큐에 오래 머물고 있다면 점진적으로 우선순위를 조금씩 올려줘서 실행을 할 수 있도록 해줌.

Round-Robin(RR)

빙빙돈다. 빙빙 돌면서 스케줄링한다.

  • Time-Sharing system(시분할/시공유 시스템): TSS에서 많이 사용하는 방법
  • Time quantum(Δ) 시간양자 = time slice (10~100msec) -> 1초동안에 보통 10~100번의 스위칭이 일어난다는 것을 의미!
    • 세 개의 프로세스가 있고 동일한 시간동안 돌아가면서 작업이 이루어지고 이 동일한 시간을 time quantum이라고 한다. 시간양자라고도 한다. 시간의 양. 시간 조각.
  • Preemptive scheduling: p1이 안끝났다고 하더라도 일정 시간이 지나면 다음 프로세스로 넘어가기 때문에

  • Example
    • AWT = 17/3 = 5.66msec
Process Burst Time(CPU 이용시간)
P1 24
P2 3
P3 3
  • Performance depends on the size of the time quantum: time quantum의 크기에 굉장히 의존적이다.
    • Δ = ∞ : 해당 프로세스가 다 사용되고 나면 스위칭됨으로 FCFS와 같다.
    • Δ = 0 : Processor sharing(* context switching overhead)
      • 스위칭이 워낙 빈번하게 일어나서 3개의 프로세스가 거의 동시에 이루어지는것처럼 보여진다.
      • 실제로 TSS가 굉장히 빈번히 스위칭이 일어나니까 동시에 프로세스를 사용하는 것처럼 보인다.
      • 근데 이는 context switching overhead가 굉장히 빈번하게 된다.
      • Dispatcher(p1에서 p2로 넘어갈때 p1의 내용을 저장하고 p2를 로드해오는 시간을 context switching overhead라고 함)가 빈번하게 되면 결코 좋은 방법이 아니다.

그래서 time slice를 너무 작게 하면 안된다.

  • Example: Average Turnaround time(ATT)
    • ATT = 11.0 msec(time quantum = 1), 12.25msec(time quantum=5)
      • 반환시간. 처음 들어간 시간부터 나온시간까지

time quantum을 얼마로 잡는가에 따라서 ATT가 되게 클수도 작을 수도 있다. 이에 따라서 성능이 달라진다. 좋은 time quantum을 잡는것이 중요하다.

Process Burst Time(CPU 이용시간)
P1 6
P2 3
P3 1
P4 7

Multilevel Queue Scheduling

  • Process group: 실행중인 프로그램들을 그룹할 수 있다.
    • system processes: os안에서 작업하는 것.
    • Interactive processes: 사용자와 대화하는 프로그램, 게임같은 것.
      • 대화하지 않는 프로그램 : compile같은 것.
    • Interactive editing processes: 컴퓨터와 대화를 굉장히 많이한다.
    • Batch processes: 꾸러미, 일괄적으로 처리하는것, 일괄적으로 컴퓨터가 알아서 하니까 내가 관여할 것이 없다.
    • Student processes

프로세스들은 이렇게 그룹을 지을 수 있다. 성격이 다양한 애들을 동일한 줄에 세우는것은 안되는것. 그러니 큐를 하나만 두는것이 아닌 여러개를 두게 되었다.

  • Single ready queue -> Several separate queues: 여러차원을 둔다.
    • 각각의 Queue에 절대적 우선순위 존재: system > interactive > batch > Student
    • 또는 CPU time을 각 Queue에 차등배분 : 한정된 CPU시간을 차등으로 배분
    • 각 Queue 는 독립된 scheduling 정책: 각각 프로세스마다 독립된 스케줄링 정책을 사용

Multilevel Feedback Queue Scheduling

Queue를 여러개 두는것은 같으나

  • 복수개의 Queue

  • 다른 Queue로의 점진적 이동

    • 모든 프로세스는 하나의 입구로 진입
    • 너무 많은 CPU time 사용시 다른 Queue로
    • 기아 상태 우려시 우선순위 높은 Queue로!

프로세스의 정의, CPU 스케줄러, 멀티 프로그래밍

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
경성대학교 양희재 교수님 수업 영상을 듣고 정리하였습니다.


프로세스 관리 (Process Management) = CPU 관리

프로그램 vs 프로세스

프로세스(process, task, job..): program in execution, 실행중에 있는 프로그램을 프로세스라고 한다.

즉, 하드디스크 안에는 프로그램, 메모리 안에는 프로세스라고 부른다.

cpu는 메인메모리 안의 process들을 관리하고 이를 관리한다는것은 cpu가 할당되어지는 시간을 관리하는 것을 의미한다.

Multiprogramming

  • new: 하드디스크로부터 메인메모리로 프로세스가 올라온 상태
  • ready: 모든 초기화를 끝내고 진짜 실행할 모든 준비가 다 된 상태
  • running: 실제로 cpu에 의해 실행상태가 됨, cpu가 실제 실행하는 상태 = 러닝 상태
  • waiting: 프린트할때는 cpu가 더이상 해당 서비스가 아닌 다음 프로세스로 넘어가 다른 프로세서의 러닝상태를 만들어주고 cpu가 실행하고 있던 프로세스는 웨이팅 상태
    • 근데 이때 프린트를 다 하고 끝나면 다시 레디 상태로 온다. 즉 다시 cpu 서비스를 받을 준비를 하고있다는 상태.
  • terminated: 프로그램이 끝난 상태

TSS

IO를 만나지 않더라도 일정 시간이 지나면 강제로 스위칭!

  • time expired: 자기에게 주어진 일정시간이 지나면 자동으로 레디로 감

PCB(Process Control Block)

  • 프로세스 제어 블록으로 TCB(Task Control Block)이라고도 부른다.
    • 이 블락안에는 프로세스에 대한 모든 정보들이 들어있음
    • 한 개의 프로세스에 대해 한 개의 PCB가 할당되며 PCB에는 프로세스에 대한 모든 정보가 들어있다.
  • 프로세스의 상태(process state)- running, ready, waiting…
  • 번지정보(PC, program counter)
  • register: 다른 레지스터들의 정보
  • MMU info(base, limit)
  • CPU Time
  • PID(Process ID, 프로세스마다의 번호)
  • list of open files(어떤 파일들을 사용하고있는지) ….

프로세스는 사람과 비슷한데, 이 PCB는 OS안의 process management 안에 들어있다. 모든 정보를 가지고 있어야 관리가 가능하고 관리를 하려면 모든 정보가 필요하다. 프로세스에 대한 정보는 모두 os안의 프로세스 관리 안에서 다 가지고 있다.

Queue

하드디스크에는 수많은 프로그램들이 있지만 이 모든 프로그램들을 메인메모리가 다 받아줄 수는 없다. 그렇기 때문에 하드디스크에서 메인메모리로 가는 과정에 대기하는 줄이 있고 그것을 Job Queue라고 한다. 그리고 메인메모리에 올라왔다고 해서 바로 서비스를 받지도 못한다. CPU는 하나뿐이기 때문에 결국 한번에 작업은 하나밖에 받지를 못한다.

즉, CPU의 작업을 받기위해서도 줄을 서서 기다려야 한다. 작업을 하고 있는 와중에 IO를 하기 위해서라도 줄을 서서 기다려야 한다.

  • Job Queue: 하드디스크에서 메인메모리로 올라올때의 대기줄
  • Ready Queue: 메인메모리에서 CPU 서비스를 받기 위한 대기줄
  • Device Queue: 프린트나 하드디스크와 같은 디바이스를 사용하기 위한 대기줄

하드디스크에서 메인메모리로 가는 프로세스의 우선순위는 어떻게 정해지는가?

= Job scheduler(long-term scheduler): 메모리에 어느 프로세스를 올릴지를 결정하는 코드로 이미 메인메모리가 꽉 차여있다면 결정할 필요가 없다.
어느 한 프로세스가 끝나 메모리가 비어지면 결정을 내리는 것으로 스케줄링은 자주 일어나지 않다.

= CPU scheduler(short-term scheduler): 프로세스간의 스위칭이 빠르게 돌아가야 한다. 1초에도 수십번씩 일어남. 컴퓨터에서는 CPU가 제일 중요!

= Device scheduler

  • OS안의 Process Management안에는 줄이 많이 서있다.(Job, Ready, Device Queue)
  • 각 줄 안에는 프로세스들이 줄을 서서 기다리고 있고
  • 각 줄에서 어느 프로세스를 먼저 꺼내서 할지를 결정하는 것은 scheduler 프로그램이 결정한다.

멀티 프로그래밍

현대의 운영체제는 대부분 다 멀티 프로그래밍이다. (하나의 메모리에 여러개의 프로세스를 올리는 것)

  • Degree of multiprogramming: 멀티프로그래밍의 정도로 메인메모리에 프로세스가 몇개 올라가져있는가를 살펴본다.
  • I/O-bound process vs CPU-bound process

: 프로세스를 크게 두개 종류로 나눔
-> I/O-bound process: IO관련 작업만 하는 프로세스, 워드같은 프로그램
-> CPU-bound process: CPU 사용하는 프로세스 (계산 많이 하는 프로세스), 슈퍼컴퓨터 사용하는 애플리케이션. 일기예보 등

골고루 사용되기 위해 job scheduler가 적절히 올려주는 것이 중요! 즉, os는 적당히 io와 cpu가 일하도록 해줘야한다!

  • Medium-term scheduler

: 대화형시스템(TSS)에서…

-> 서버컴퓨터를 두고 여러 사용자가 컴퓨터를 사용하고 있다고 하자. 서버컴퓨터 내의 메모리에는 각각 사용자에 대한 프로세스들이 준비되어있을 것이다. 그런데 한 사용자가 잠시 작업을 중단했다고 하자. 그렇다는 것은 그 사용자를 위한 메모리는 현재 준비되어있지만 아무것도 하고 있지 않음을 의미한다. 실제 CPU 또한 그 사용자의 일을 하지 않을 것이다. CPU 입장에서는 해당 사용자의 메모리 사용이 아까울 것이다. os의 프로세스 관리부서(cpu사용시간을 관리하는 부서)에서 메모리를 사용하지 않음을 발견하고 이를 하드디스크에 메모리 전체를 쫓아낸다.(swap out) 비어진 메모리 공간에는 다른 프로세스를 올릴수도 있고 나머지 프로세스의 메모리 크기를 더 크게 해줄 수 있게 된다.

  • swapping: 메인메모리에서 하드디스크로 쫓아내는 행위(swap out) 프로세스 이미지를 쫓아내는 행위로서 디스크를 사용하는 것(backing store-swap device), 사용자가 다시 돌아와서 해당 프로세스를 사용하고자 하여 디스크에 들어갔던 프로세스를 다시 메모리로 가져오는 행위(swap in) 이 모든 행위를 swapping이라고 한다.

즉, medium-term scheduler은 스케줄링이 중간 즈음에 일어나는 것을 의미한다. os가 지켜보고 있다가 어떤 애를 몰아낼 것인지를 결정하는것으로 os가 쭉 메모리를 뒤져가지고 현재 사용되지 않은 어느 놈을 하드디스크로 몰아낼 것인가를 결정하는 것을 의미한다.

  • Context switching(문맥전환)

프로세스가 메인메모리에 여러개 있어도 CPU에서는 하나밖에 일 하지 못한다. 따라서 프로세스간의 이동을 말한다.

  • Scheduler: 다음에 무엇을 할지를 결정하는것. 지금 프로세스 다음 어느 프로세스를 할 것인지 결정하는 컴퓨터 프로그램
  • Dispatcher: 실제로 스케줄러가 선택한 프로세스를 실행하도록 상태, 값을 바꾸어주는 행위 -> p1의 현재 상태를 os의 PCB에 다 저장해놔야 한다. 나중에 다시 돌아왔을때 그 상태로 돌아갈 수 있도록 -> MMU의 base, limit 정보도 PCB에 저장해놓는다 -> p1에서 p2를 넘어가려면 p1의 현재 상태를 PCB 에 저장해놓아야 한다. -> restore -> 이는 os안의 Dispatcher라는 프로그램이 해준다. -> context switching overhead: 저장하고 복원할때마다의 부담이 있기 때문에 이를 너무 자주하면 안된다. overhead의 숫자가 너무 많아진다. 이를 줄이는게 좋음!

운영체제의 주요서비스 - 프로세스, 메모리, 파일관리, 시스템호출

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
경성대학교 양희재 교수님 수업 영상을 듣고 정리하였습니다.


application: 하드웨어의 자원을 사용
hardware: resource
os: 하드웨어 자원을 효율적으로 어플리케이션에게 나누어줌

이런 os에는 여러가지 관리들이 있는데

  • process management(cpu, 프로세서 관리)
  • memory management(메인메모리 관리)
  • file management(하드디스크)
  • IO management
  • networking
  • protection..

그러면 각 부서에서는 무슨일들을 하는가?

1. 프로세스 관리(Process Management)

프로세스: 실제 메인 메모리에서 실행 중인 프로그램 (program in execution)

cpu에 의해서 실행되는 프로그램은 메인 메모리 위로 올라와있는 프로그램이니까 cpu와 관련해서는 프로그램관리가 아닌 프로세스 관리라고 한다. 이들은 os의 프로세스 관리 부분이 처리해준다.

  • 프로세스의 생성, 소멸(creation, deletion)
  • 프로세스 활동 일시 중지, 활동 재개(suspend, resume)
  • 프로세스 간 통신 (interprocess communication, IPC)
  • 프로세스 간 동기화 (synchronization)
  • 교착상태 처리(deadlock handing

2. 주기억장치 관리(Main Memory Management)

  • 프로세스에게 메모리 공간 할당(allocation)
  • 메인메모리의 어느 부분이 어느 프로세스에게 할당되었는가를 추적/감시
  • 프로세스 종료 시 메모리 회수 (deallocation)
  • 메모리의 효과적 사용
  • 가상메모리: 물리적 실제 메모리보다 큰 용량 갖도록 해줌
    • 일반적으로 메인메모리는 보조기억장치에 비해서 용량이 작다. 실제 메모리는 조금밖에 없지만 크게 보이도록 하는 기술이 가상메모리임

3. 파일관리 (File Management)

Track/Sector로 구성된 디스크를 파일이라는 논리적 관점으로 보게 관리

  • 파일의 생성과 삭제(file creation/deletion)
  • 디렉토리(directory)의 생성과 삭제(또는 폴더 folder)
  • 기본동작지원: open, close, read, write, create, delete
  • track/sector - file 간의 매핑(mapping)
  • 백업(backup)

4. 보조기억장치 관리 (Secondary Storage Management)

하드디스크, 플래시 메모리 등

  • 빈공간 관리(free space management): 처음에는 블락들이 하나도 사용안되고 있다가 사용된다면 그 해당 공간들을 관리
  • 저장공간 할당(storage allocation): 3개의 블락이 필요하다면 비어있는 공간중에 어느 블락을 사용할것인지 처리
  • 디스크 스케줄링(disk scheduling): 블락들이 흩어져있는데 헤드를 많이 움직이면 시간이 많이 걸릴테니 최소한의 움직임으로 원하는 track/sector를 읽어올 것인가를 결정

5. 입출력장치 관리 (I/O Device Management)

장치 드라이브 (Device driver), 장치를 사용하기 위한 드라이브가 필요한데 이 드라이브는 os에 포함되어있다.

  • 입출력 장치의 성능향상: buffering, caching, spooling
    • buffering: 입출력장치에서 읽은 내용을 일단 메모리에 들고옴, 그래야 나중에 또 그 파일을 쓸때 시간을 줄여서 사용할 수 있다.
    • caching: buffering과 비슷
    • spooling: 메모리 대신 하드디스크를 중간매체로 사용. 프린트로 글자를 찍는다면 프린트는 속도가 느리니까 일단 하드디스크에 저정하고 그 내용을 프린트에 보냄으로써 그 사이 cpu는 다른일을 할 수 있도록 한다.

시스템 콜(System calls)

일반 애플리케이션 서비스가 os가 제공하는 서비스를 받기 위해서 호출하는것. 즉, 운영체제 서비스를 받기 위한 호출을 의미한다.

  • Process: end, abort(강제종료), load(하드디스크의 프로그램을 메모리에 가져오는 것), execute, create(프로세스를 만들고), terminate(=end), get/set, attributes, wait event, signal event
  • Memory: allocate, free(메모리 되돌려줌)
  • File: create, delete, open, close, read, write, get/set attributes
  • Device: request, release, read, write, get/set attributes, attach/detach devices
  • Information: get/set time, get/set system data
  • communication: socket, send, receive
<순서>
EAX: 해당하는 명령
ECX = attributes
EBX = file name
swi
-> 원하고자 하는 파일이 생성됨
일반 어플리케이션이 os에 요청하는 것을 `system call` 이라고 하고, 시스템 콜은 일반적으로 특정 레지스터에 특정 값을 건 후에 swi를 걸어봄으로써 서비스를 받을 수 있다.