3. 프로세스

lsy·2022년 10월 22일
0

운영체제

목록 보기
3/10

프로세스와 문맥

프로세스는 실행중인 프로그램이다.

프로그램이 실행되면서 변경되어 온 상태들이 있을텐데 그것들 현재에 나타낸 것을 프로세스의 문맥이라고 한다. 프로세스 문맥은 3가지로 나뉘어진다.

cpu 수행 상태를 나타내는 하드웨어 문맥

  • 프로그램 카운터, 각종 레지스터

프로세스의 주소 공간

  • code, data, stack

프로세스 관련 커널 자료 구조

  • PCB, 커널 stack

프로세스의 상태

프로세스의 상태는 크게 3개로 나뉜다.

Running

  • cpu를 잡고 instruction을 수행중인 상태

Ready

  • cpu를 기다리는 상태(메모리 등 다른 조건을 모두 만족하고 언제든 cpu를 받으면 Running 할 수 있는 상태)

Blocked

  • cpu를 주어도 당장 instruction을 수행할 수 없는 상태
  • 프로세스 자신이 요청한 이벤트(예: I/O)가 즉시 만족되지 않아 이를 기다리는 상태
  • ex) 디스크에서 file을 읽어와야 하는 경우

이에 두가지를 더 추가해서 설명하기도 한다.

New

  • 프로세스가 수행중인 상태

Terminated

  • 수행이 끝난 상태(종료중인 상태)

위 그림은 프로세스의 상태도를 나타낸 그림이다.

PCB

PCB는 운영체제가 각 프로세스를 관리하기 위해 프로세스당 유지하는 정보다. PCB에는 다음과 같은 정보가 있다.

1. OS가 관리상 사용하는 정보
2. CPU 수행 관련 하드웨어 값
3. 메모리 값
4. 파일 관련

문맥 교환

cpu를 한 프로세스에서 다른 프로세스로 넘겨주는 과정을 문맥 교환이라고 한다. 문맥 교환은 프로세스의 Timer가 끝나거나, 인터럽트를 받거나, 또는 system call을 받아 다른 프로세스로 cpu를 넘겨줄 때 일어난다. 문맥 교환은 다음과 같은 순서로 일어난다.

  1. cpu를 내어주는 프로세스의 상태를 그 프로세스의 PCB에 저장한다.
  2. cpu를 새롭게 얻는 프로세스의 상태를 PCB에서 읽어온다.

다만, system call이나 인터럽트를 받는다고 반드시 문맥 교환이 발생하는 것은 아니다.

위 그림에서 1번의 경우, 사용자 프로세스가 인터럽트나 system call을 받아 커널 모드에 진입하고, interrupt service routine이나 해당하는 system call 함수를 실행한다. 그 후 다시 유저 모드로 복귀하고 있다. 이 과정에서 cpu는 유저 모드에서 커널 모드로 바꿀뿐 계속 해당 프로세스를 running 하고 있다(운영체제가 running중인게 아니다). 따라서 문맥 교환이 일어나지 않는다.

2번의 경우에는 평범한 인터럽트가 아니라 timer interrupt를 프로세스가 받거나, I/O system call을 프로세스가 요청하고 있다. timer interrupt는 다른 프로세스로 cpu를 넘겨주어야 하고, I/O 요청의 경우 시간이 오래 걸리므로 해당 프로세스를 Block하고 다른 프로세스에게 cpu를 넘겨주어야 한다. 따라서 이 과정에서는 문맥 교환이 일어난다.

물론, 1번의 경우에도 PCB에 문맥의 일부를 저장하지만 2의 오버헤드가 훨씬 크다.

스케줄러

스케줄러는 프로세스를 실행하기 위해 메모리 공간 관리, cpu의 프로세스 처리 순서 등을 조절하는 역할을 한다. 스케줄러의 종류는 다음과 같다.

장기 스케줄러 (Job scheduler)

  • 시작 프로세스 중 어떤 것들을 레디 큐로 보낼지 결정
  • 프로세스에 메모리, 각종 자원등을 주는 문제를 해결함
  • 메모리에 올라가있는 프로그램의 수를 제어
  • 시분할 시스템에는 보통 장기 스케줄러가 없음(무조건 Ready 상태가 되기 때문)

단기 스케줄러 (Cpu scheduler)

  • 어떤 프로세스를 다음번에 running할지 결정
  • 프로세스에 cpu를 주는 문제를 해결함
  • 충분히 빨라야함

중기 스케줄러 (Swapper)

  • 여유 공간 마련을 위해 프로세스를 통째로 메모리에서 디스크로 쫓아냄
  • 프로세스에게서 메모리를 뺏어옴
  • 메모리에 올라가있는 프로그램의 수를 제어

이러한 처리를 위해, 스케줄러는 queue라는 곳에 프로세스를 대기하도록 하는데, 그 종류는 다음과 같다.

Job queue

  • 현재 시스템 내에 있는 모든 프로세스의 집합

ready queue

  • 현재 메모리 내에 있으면서 cpu를 잡아서 실행되기를 기다리는 프로세스의 집합

device queues

  • io device의 처리를 기다리는 프로세스의 집합

위와 같이 여러 큐에 들어가 대기하게 되고 차례가 되면 처리된다.

현 시분할 시스템의 중기 스케줄러때문에 새로 추가된 프로세스의 상태가 있는데 바로 Suspended(stopped)상태다.

이 상태는 외부적인 이유로 프로세스의 수행이 정지된 상태로, 이 상태에 들어간 프로세스는 통째로 디스크에 swap out된다. 예를 들어 사용자가 프로그램을 일시정지시킨 경우가 있고, 시스템이 메모리에 너무 많은 프로세스가 올라와 있을 때 알고리즘에 따라 골라서 잠시 중단 시킨다.

Suspended와 Blocked의 차이점은, Blocked는 자신이 요청한 event가 만족되면 다시 ready 상태에 들어가고, Suspended는 외부에서 재개시켜줘야 다시 동작한다. 물론 Suspended상태에서 아무것도 못하는 것은 아니고, I/O 작업은 가능하다.

위 사진은 추가된 상태까지 합한 프로세스의 상태도이다.

쓰레드(lightweight process)

프로세스 내에 수행 단위가 여러개 있는 경우를 쓰레드라고 한다. 쓰레드는 다음과 같이 구성된다.

program counter
register set
stack space

그리고 쓰레드끼리 공유하는 부분도 존재한다.

code section
data section
os resource

이것이 무슨 말인지는 아래 그림을 보면 알 수 있다.

위에서 설명한 것처럼 주소 공간에서 함수 사용에 관련한 정보인 stack은 각자 가지고 있고, data와 code는 전부 공유한다. PCB에서는 OS 관리용 정보와 자원 관련 정보는 공유하고, cpu 관련 정보(프로그램 카운터, 레지스터)는 각자 가지게 된다.

쓰레드를 사용하면 하나의 쓰레드가 Block 상태가 되어도 동일한 태스크 내의 다른 쓰레드가 Running되어 빠른 처리가 가능하다. 또 동일한 일을 수행하는 다중 쓰레드가 협력하여 높은 처리율과 성능 향상을 얻을 수 있다.

그렇다면 왜 프로세스를 여러 개 만들지 않고 쓰레드를 사용할까? 왜냐하면 프로세스를 여러 개 만드는 것은 메모리 낭비가 매우 심한 일이고, 거기다가 프로세스 생성과 프로세스끼리의 cpu swiching은 쓰레드를 생성하여 쓰레드끼리의 cpu swiching보다 오버헤드가 매우 심하기 때문이다.

정리하면 쓰레드의 장점은 다음과 같다.

1. 응답성
2. 자원 공유
3. 자원 소비가 적음

커널 쓰레드와 유저 쓰레드

커널 쓰레드

  • 커널의 지원을 받는 쓰레드다.
  • 커널이 쓰레드가 여러 개 있다는 사실을 알고 있다.
  • 하나의 쓰레드에서 다른 쓰레드로 넘어갈 때 cpu 스케줄링 하듯이 넘겨주게 된다.

유저 쓰레드

  • 라이브러리를 통해 지원되는 쓰레드다. (ptherad, java thread..)
  • 프로세스 안에 쓰레드가 여러 개 있다는 사실을 커널은 모르고 유저 프로그램이 스스로 관리한다.
  • 커널이 볼 때는 하나의 프로세스처럼 보인다.

반효경 교수님의 운영체제 강의를 바탕으로 작성했습니다

profile
server를 공부하고 있습니다.

0개의 댓글