[OS] Processes and Threads

메르센고수·2024년 3월 31일
0

Computer Science

목록 보기
3/11


Process라고 하면 흔히 "현재 실행 중인 프로그램"이라고 알고 있다. 그러나 더 깊이 들여다보면 Process도 하나의 자료구조 (data structure)라는 것을 알 수 있다.
지금부터 왜 Process를 자료구조로 여기는지 확인해볼 것이다.


Process

process는 크게 4가지의 영역으로 구분되어 있고 주소공간 (Address space)의 개념으로 관리된다.

  • text : code가 저장되는 영역으로 static한 영역이다.
  • stack : function call이나 context switch에 사용되기 때문에 function call에서 쓰이는 parameter, return address, local variable 등과 context switch에 필요한 PC(%rip)stack pointer(%rsp)의 값들이 저장된다. 이 영역의 경우 dynamic한 영역이기 때문에 크기가 동적으로 변한다.
  • data : static variable이나 global variable과 같이 여러 파일들에서 참조하는 변수들, 즉 어디에서나 접근 가능한 data를 저장한다. 이 영역의 경우 변수를 선언해 놓으면 참조만 하면 되기 때문에 static한 영역이다.
  • heap : C언어에서의 malloc과 같이 dynamic allocation을 위한 영역이다. 크기가 동적으로 변하기 때문에 당연히도 이 영역은 dynamic한 영역이다.

이를 그림으로 나타내면 아래와 같다.
(필기는 양해부탁드립니다)

그리고 process의 경우 2가지로 설명할 수 있다.

첫 번째로 I/O-bound process가 있다. 이 경우 hwp, ppt와 같이 user의 입력이 있는 경우 입력할 때마다 CPU가 일하고 입력이 없는 경우 다음 I/O event가 있을때까지 기다린다. 따라서 CPU 사용시간이 매우 짧은 반면 발생 빈도는 높기 때문에 many short CPU bursts라고 표현한다.

두 번째로 CPU-bound process가 있다. 이 경우는 I/O event보다 연산에 더 많은 시간을 사용하기 때문에 I/O bound process와 반대로 발생 빈도가 적고 한번 CPU가 할당되면 최대한 오래한 사용하려고한다. (few very long CPU bursts)

이 둘 중에 어떤 것이 우선이 되어야 할까? 쉬운 예시로 카톡과 소인수분해 연산이 있다. 만약 사용자가 카톡을 하면서 소인수분해를 동시에 하고 있다면, CPU를 어느 프로세스에게 먼저 줘야할지 정해야한다. 이 경우 만약 소인수분해에게 CPU를 먼저 할당해준다면 연산이 모두 끝날때까지 카톡을 못하게 된다. 물론 연산 수행속도가 느린 것은 아니지만, 사용자에게는 둘의 차이가 체감될 것이다. 그렇기 때문에 I/O bound process에게 우선권을 주어야 한다.

Process State


Process가 실행을 시작하게 되면 state를 바꿔서 현재 어떤 작업이 진행중인지를 나타낸다.

  • new : Process가 이제 막 생성된 상태로, content가 채워져 memory에 탑재는 되었지만 아직 CPU Scheduling을 통해 CPU를 할당 받기 위한 상태는 아니다.
  • ready : new state인 process가 admit 되게 되면 processor에 할당될 준비를 하게 되는데 이 상태를 ready라고 한다. Process가 실행될 준비를 모두 마친 상태이기 때문에 CPU만 할당된다면 바로 실행이 가능하다.
  • running : CPU가 할당되어 Process가 실행중인 상태이다. 만약 여러 Process가 실행을 해야할 경우 (Multiprogramming) CPU scheduler가 지금 실행할 Process에게 CPU를 할당하고 Process가 끝나면 다른 Process에게 CPU 사용권을 넘겨야 하는데 이 과정을 Scheduler dispatch라고 한다. 이 과정을 통해 CPU 사용을 최대화 하고 응답시간을 최소화해서 성능을 향상시킬 수 있다.
  • waiting : waiting 상태의 경우 실행중인 process가 interrupt와 같은 event가 발생했을 때 잠시 실행을 멈추고 event 처리가 끝날 때까지 기다리고 있는 상태이다. waiting 상태가 끝나게 되면 다시 running 상태로 가는 것이 아니라 ready 상태로 가서 다시 CPU 할당을 기다리게 된다.
  • terminated
    : 마지막으로 terminated 상태는 process의 instruction이 모두 끝나고 아직 process가 소멸하지 않은 상태이다. 즉, Process의 execution만 끝난 상태이다.

Process Control Block (PCB)

운영체제가 프로세스를 제어하기 위해 정보(CPU 레지스터 값들)를 저장해 놓는 곳으로 프로세스의 상태 정보를 저장하는 구조체이다. Linux에서는 task_struct 라고 정의하며 PCB에 저장되는 정보는 다음과 같다.

PCB
Process state
Program Counter
CPU registers
CPU scheduling information
Memory-management information
Accounting information
I/O status information

CPU Switch


interrupt의 과정과 같지만, 위에서 언급한 PCB의 관점으로 설명하면 interrupt가 발생했을 때, interrupt handler에 의해 interrupt 처리가 끝난 뒤 다시 돌아와서 원래의 process를 실행하기 위해 저장을 해야 하는데 그것을 PCB에 한다. 즉 각각의 Process에 대응하는 PCB 번호에 process에 대한 정보를 저장해놓고 그때그때 사용하면서 정보를 저장하고 loading하는 과정을 반복하게 된다.

Process Scheduling Queue

  • Job queue : 모든 processe들의 집합
  • Ready queue : main memory에 있는 process들 중 ready/waiting 상태인 모든 process들의 집합
  • Device queues : I/O device를 기다리고 있는 process들의 집합이다.

Schedulers

Scheduler란 쉽게 말해 process들의 일정표를 짜는 방법을 의미한다. 즉 어떤 process에게 CPU를 할당하고 process간의 순서를 정해서 보다 효율적인 CPU 사용과 process의 실행을 가능하게 하는 존재이다.

Long-term scheduler (job scheduler)

: 어떤 process를 ready queue에서 가져와야 하는지를 결정하는 scheduler이다.
이 scheduler의 경우 degree of multiprogramming을 제어하고 자주 요청할 필요가 없기 때문에 느리다.

  • degree of multiprogramming
    : 현재 CPU를 통해 일을 하고 있는 모든 process들의 개수 (CPU scheduling의 대상이 되는 process들의 개수)

Short-term scheduler (CPU scheduler)

: 어떤 process를 다음에 실행할지를 결정하고 CPU를 할당해주는 scheduler이다. 그렇기 때문에 빈도가 매우 높고 속도가 매우 빨라야 한다.

Medium-term scheduling

: Multiprogramming을 위한 작업으로, Memory의 공간을 확보하는 것이 주 목적이다. Swap in/out으로 지금 사용하지 않는 process는 Disk로 보내고 지금 사용할 process를 memory로 가져온다.

Context Switch

CPU가 다른 process로 전환을 하려고 할 때 기존에 실행중이던 process를 어딘가에 저장해두고 새로 실행할 프로세스를 실행해야 기존 process를 잃어버리지 않는다. 이 때 저장하는 공간 (자료구조)이 위에서 언급한 PCB이고 register와 PCB 사이를 왔다갔다 하며 data를 저장하고 load한다. 그러나 Context Switch 역시 overhead이기 때문에 시간이 오래걸리고 hardware에 의존적이다. 따라서 pointer로 context switch를 하는 방식이 떠오르고 있다고 한다.

Threads


Thread의 경우 Context Switch에서 발생하는 Overhead를 줄이고자 최대한 공유할 수 있는 data (전역 변수, code 등)는 공유하고 지역 변수나 function call 같이 thread마다 다른 data는 각각의 thread가 실행하도록 하는 방식이다. 이 방식을 통해 Address space만 공유하여 하나의 process에서 여러 작업을 수행할 수 있게 된다.

Thread의 장점

  1. Responsiveness : program의 일부가 interrupt와 같은 event에 의해 막히거나 긴 operation을 수행중이여도 계속 실행할 수 있도록 한다.
  2. Resource Sharing : 같은 주소공간을 사용하기 때문에 다른 thread가 같은 자원을 공유할 수 있다.
  3. Economy : process 여러개를 생성하여 context switch를 하는 것보다 thread 여러개를 만들어서 공유할 건 공유하고 공유하지 않는 자원들만 따로 만들어서 하는 것이 훨씬 cost가 적다.
  4. Scalability : 다른 processor에서 각각의 thread를 병렬적으로 수행할 수 있다.
profile
블로그 이전했습니다 (https://phj6724.tistory.com/)

0개의 댓글