운영체제

[운영체제(OS)] 5. 프로세스와 스레드 (Processes And Threads)

용성군 2021. 7. 27. 00:50
728x90
반응형

Process Concept

프로세스란?

  • 실행 중인 프로그램(즉 메모리에 올라간 프로그램을 가르킨다)
  • 프로그램 실행은 순차적인 방식으로 진행되어야 한다.(만들어진 코드들이 순차적으로 진행되어야한다)


프로세스는 다음을 포함한다.

  • 텍스트 섹션(text section): 프로그램 코드
  • 프로그램 카운터(PC) 및 레지스터 값
  • 스택(stack): 매개변수, 반환 주소(return address), 지역 변수(local variable) 등을 저장한다.
  • 데이터 섹션(data section): 정적변수(static variable)와 전역 변수(global variable)를 저장합니다.
  • 동적 할당을 위한 힙 섹션(사용 가능한 메모리 풀에서 찾아서 할당해줌)

다음은 메모리에 있는 process의 주소공간을 나타냅니다. 0번부터 max번지 까지 주소가 존재하고 stack과 heap영역은 가변적이다. 이 두개의 section은 만날 수 없을 만큼 크다. 

프로세스 주소공간


Process state

프로세스가 실행되면 상태가 바뀌게 된다.

  • new: 프로세스가 생성 중
  • running: instruction이 실행 중
  • wait: 프로세스는 event(예를 들면 I/O)가 발생하기를 기다리고 있음
  • ready: 프로세스가 processor에 할당되기를 기다리는 중
  • terminated: 프로세스가 실행을 마침.

new 상태는 CPU scheduling에 포함되지 않는다. CPU를 할당받아도 될것 같다면 new에서 ready 상태로 이동한다. 

running 상태에서 ready 상태로 interrupt가 발생하는 것은 할당된 cpu시간이 끝났을 때 timer device가 보내주는 interrupt이다.

I/O가 끝나면 wating에서 ready상태로 이동한다. 

프로세스의 상태 diagram


Process Control Block(PCB)

PCB란 프로세스를 나타내는 커널 데이터 구조(kernel data structure)(예: Linux의 task_struct)이고 다음을 포함한다. 

  • 프로세스 상태(Process state)
  • 프로그램 카운터(Program counter)
  • CPU 레지스터(CPU register)
  • CPU 스케줄링 정보(CPU scheduling information)
  • 메모리 관리 정보(Memory-management information)
  • I/O 상태 정보(I/O status information)

다음은 P0 프로세스에서 P1 프로세스로 CPU가 바뀔 때의 그림이다.

P0 프로세스가 실행하다가 interrupt 나 system call이 발생하면 현재의 상태를 PCB0에 저장한다. 그리고 P1 프로세스 PCB1에서 상태를 불러와 P1 프로세스를 실행한다. 이것을 Context Switching이라고도 한다. 

 


Process Scheduling Queues

Job queue
시스템 상의 모든 프로세스 집합. 즉 모든 process들이 queue안에 존재한다. 

Ready queue
메인 메모리에 있는 모든 프로세스의 집합으로 실행 준비가 되어 있고 대기 중입니다. 즉 CPU를 기다리는 queue이다.

Device queues
I/O 장치를 기다리는 프로세스 집합으로 wait 상태에 있는 process들이 존재한다. 

프로세스들은 다양한 queue 간에서 이동한다.


Schedulers

Long-term scheduler (또는 job scheduler)

  • Ready queue로 가져올 프로세스를 선택한다.
  • new에서 ready 상태로 바꾸는 scheduler이다.

Short-term scheduler(또는 CPU scheduler)

  • 다음에 실행할 프로세스를 선택하고 CPU를 할당한다.
  • ready에서 running 상태로 바꾸는 scheduler이다.

추가적으로 memory가 부족하면 process를 disk로 swap-out시키고 필요할 때 swap-in 시키는 Medium Term scheduler가 있으며 다음은 medium term scheduler의 그림이다. 

Medium Term scheduler

Short-term scheduler는 자주 호출된다(밀리 초마다 호출되기 때문에 빠른 속도여야 함).

Long-term scheduler는 드물게 호출된다(초, 분마다 호출되기 때문에 느릴 수 있음)

Long-term scheduler는 multiprogramming of degree를 제어한다.

(multiprogramming of degree는 cpu가 잡아서 일을 하는 process의 수를 말하는데 Long-term scheduler는 ready queue로 들여오기 때문에 이것을 제어한다고 할 수 있다)

프로세스는 다음 중 하나로 설명할 수 있다.

  • I/O bound 프로세스 – 계산(computations)보다 I/O 수행에 더 많은 시간을 소비합니다. CPU를 짧게 많이 사용하는 프로세스를 가르킨다.
  • CPU bound 프로세스 – 계산(computations)에 더 많은 시간을 할애한다. 한번 CPU를 잡으면 길게 사용한다.

 Context Switch

  • Context는 문맥이라는 영어처럼 한process에서 다른 process로 문맥을 바꿔주는 것으로 Context는 PCB에 표현된 process를 뜻한다.
  • CPU가 다른 프로세스로 전환할 때 시스템은 현재 프로세스의 상태를 저장하고 Context Switch를 통해 새 프로세스의 상태를 로드해야 합니다.

Context switch는 오버헤드가 발생한다.

  • switching하는 동안에 시스템은 유용한 일을 하지 못하기 때문에 빠르게 Context switch를 하는 것이 좋다.
  • 따라서 하드웨어의 도움을 받는다.
    • Intel CPU는 Context switch를 위해 HW를 지원한다. 상태 저장 및 복원은 SW가 아닌 HW에서 수행된다.
  •  Context switch는 cache flushing(캐시를 비우는 것)을 동반한다. → Context switch 후에 연속적인 cache miss가 발생합니다.

Process Creation

Parent process는 Child process를 생성하고, 이는 차례로 다른 프로세스를 생성하여 프로세스 트리를 형성합니다.

일반적으로 프로세스 식별자(pid)를 통해 프로세스를 식별하고 관리합니다.

Resource sharing(자원 공유)

  • 부모와 자식 프로세스는 모든 자원을 공유할수도 공유하지 않을 수도 있다.

Execution

  • 부모와 자식은 동시에 실행된다.
  • 부모는 자식이 종료될 때까지 기다린다.

Address space(주소 공간)

  • 자식은 만들어지면 부모의 주소 공간을 그대로 복사한다.

UNIX프로그램에서의 예제

  • fork() system call은 새로운 프로세스를 생성한다.
  • 프로세스의 메모리 공간을 새 프로그램으로 교체하기 위해(parent에서 child로 교체하기위해) exec() system call 호출

자식 프로세스 특징

  • fork() system call 호출 후 자식 프로세스는 부모 프로세스와  동일한 context 값(프로그램 카운터, 레지스터, 메모리 정보, open file 정보 등)을 갖는다.
  • 따라서 자식 프로세스와 부모 프로세스 같은 지점에서 실행된다.
  • 자식 프로세스에서의 fork() system call return 값은 0이고 부모 프로세스에 대한 return 값은 자식 프로세스의 PID이다.

다음은 parent 프로세스에서 child 프로세스를 실행시키는 코드이다. 

fork()를 호출하면 child 프로세스의 pid는 0이 되어 execlp()실행되고 parent 프로세스는 child 프로세스가 끝날 때까지 기다린다.(wait() 함수 실행)

#include <stdio.h>

void main (int argc, char *argv[]) {

  int pid;
  /* fork another process */ 
  pid = fork();

  if (pid < 0) { 
    /* error occurred */ 
    fprintf (stderr, “Fork Failed\n”); 
    exit(-1);
  }
  else if (pid == 0) { 
    /* child process */ 
    execlp(“/bin/ls”, “ls”, NULL);
  }
  else { 
    /* parent process */
    /* parent will wait for the child to complete */
    wait(NULL);
    printf(“Child Complete\n”);
    exit(0); 
  }
}

Threads

스레드(또는 lightweight process라고 불림)는 CPU 사용의 기본 단위이며 다음과 같이 구성된다

  • 프로그램 카운터(program counter)
  • 레지스터
  • 스택 공간

스레드는 주변 스레드와 다음을 공유합니다.

  • 코드 섹션(code section) 
  • 데이터 섹션(data section)
  • open file과 같은 운영 체제 자원들

기존 프로세스(heavyweight process라고 불림)는 하나의 스레드를 가지고 작업하는것과 같다.


Single Thread와 Multi Thread

  • 단일 스레드는 register, stack, code, data등을 가진다.
  • 다중 스레드는 스레드끼리 code, data, file을 공유하지만 stack과 register는 각각의 스레드가 가지고 있다.


스레드의 장점

Responsiveness(응답성)

  • 프로그램의 일부가 차단되거나 긴 작업을 수행하는 경우에도 프로그램이 계속 실행되도록 허용.
  • 정리하면 signle thread는 I/O 발생시 멈춰있을 수 밖에 없지만 multi-thread는 한개의 thread에 I/O를 발생하였더라도 다른 일을 수행할 수 있다. 

Resource Sharing(자원 공유)

  • 동일한 주소 공간 내에서 여러 다른 스레드들이 자원을 공유한다.
  • multi-thread가 아닌 다중 프로세스를 사용하게 되면 공유할 수 있는 자원도 만들어야 하기 때문에 비효율적일 수 있다. 

Economy(경제성)

  • 프로세스보다 스레드를 생성하고 스레드를 context switch하는 것이 더 경제적이다.
  • 프로세스는 여러개를 만들려면 address space를 복사해야하기 때문에 오래걸린다. 따라서 스레드가 훨씬 경제적이다.

Scalability(확장성)

  • 각 스레드는 다른 프로세서에서 병렬로 실행될 수 있습니다.
  • multicore system에서 하나의 프로세스에 single thread라면 여러개의 core에서 동작하지 않고 multi-thread에서는 여러개의 core에서 동작이 가능하다. 
728x90
반응형