본문 바로가기
Learning-log -CS/운영체제

(운영체제 / 반효경) 3-2. Process (PCB, 문맥 교환, Queue, 스케줄링, 스레드(Thread))

by why제곱 2024. 4. 5.

Process Control Block (PCB)

운영체제가 각 프로세스를 관리하기 위해 프로세스마다 해당 프로세스의 정보를 구조체로 구성해 저장하는 정보이다.

이러한 PCB를 구성하는 요소를 4가지로 나누어 살펴보자.

OS가 관리상 사용하는 정보

프로세스 상태, PID(Process ID), 스케줄링 정보, Priority를 담고 있다.

Priority는 Queue에 먼저 온 순서대로 처리하지 않고 스케줄링 기법마다 가진 우선순위에 대한 정보를 나타낸다.

CPU 수행 관련 하드웨어 값

Program Counter와 Registers가 있다. CPU에 어떤 레지스터 값을 넣어서 실행하고 있었는지를 나타낸다.

메모리 관련

code, data, stack이 메모리의 어디에 위치해있는지에 대한 정보가 있다.

파일 관련

해당 프로세스가 어떤 파일을 사용하고 있느지에 대한 정보를 나타낸다.

 

 

문맥 교환 (Context Switch)

CPU를 한 프로세스에서 다른 프로세스로 넘겨주는 과정을 문맥 교환이라고 한다. 앞선 게시물에서 살펴봤듯, 여러 프로세스들이 짧은 간격으로 CPU를 얻고 뺏기는 과정을 반복한다. CPU를 뺏겼다가 다시 얻을 때, 기억해둔 문맥을 보고 뺏긴 시점부터 다시 실행할 수 있게 하는 것이다.

CPU가 다른 프로세스로 넘어갈 때 운영체제는 CPU를 내어주는 프로세스의 상태를 해당 프로세스의 PCB에 저장하고 새로 넘어갈 프로세스의 상태를 그 프로세스의 PCB에서 읽어 온다.

여기서 CPU가 사용자 프로세스에서 다른 프로세스를 넘어가는 과정을 말한다는 것을 명심해야 한다. Kernel Mode와 User Mode의 상태 변환을 말하는 것이 아니니 주의하자. System Call이나 하드웨어 인터럽트가 발생할 때 반드시 문맥 교환(Context Switch)이 발생하는 것은 아니라는 점에서 주의해야 한다. 위 과정은 CPU가 다른 프로세스가 아닌 운영체제로 넘어간다. 이는 문맥 교환이 아니다.

타이머 인터럽트의 경우 CPU를 다른 프로세스에 넘기기 위한 의도를 가진 인터럽트다. 따라서 실행 중이던 프로세스에서 다른 사용자 프로세스에게 CPU를 넘기게 되므로 이럴 때는 문맥 교환이 발생한다. I/O 작업 요청의 경우에도 다른 프로세스에게 CPU를 넘기게 되어 문맥교환이 발생한다.

즉, 인터럽트와 시스템 콜이 발생하면 무조건 문맥교환이 발생하지는 않는다. 위와 같이 문맥 교환이 발생하기도, 안하기도 하므로 둘을 동일시 하지 말자. 문맥교환은 오직 프로세스에서 다른 프로세스로 CPU가 넘어갈 때를 말한다는 것만 명심하면 헷갈리지 않는다.

 

 

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

프로세스들이 CPU를 얻기 위해 Queue에 줄을 선다는 것을 살펴봤었다. 프로세스들이 줄 서 있던 Queue의 종류들을 살펴보자.

Job Queue

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

Ready Queue

현재 메모리 내에 있으면서, CPU를 기다리는 프로세스의 집합

Device Queue

I/O 디바이스의 처리를 기다리는 프로세스의 집합

프로그램이 모바일에 올라오면 Ready Queue에 등록되고 자신의 차례가 오면 CPU를 얻어 실행한다. I/O요청이 들어오거나 할당 시간이 끝나면(타임 인터럽트) 다시 Ready Queue로 들어간다. CPU에서 본인의 할 일이 모두 끝난 프로세스는 terminate로 빠져나간다.

스케줄러 (Scheduler)

단기 스케줄러 (Short-term scheduler, CPU scheduler)

매우 짧은 시간 단위(ms)로 이뤄지며, 다음 번에 어떤 프로세스에게 CPU를 줄 지 결정한다.

장기 스케줄러 (Long-term scheduler, Job scheduler)

메모리를 어떤 프로세스에게 줄 지 결정한다. 프로세스가 시작될 때인 New 상태에서 CPU 제어권을 가질 기회를 얻기 위해서는 Ready 상태가 되어야 한다. 여기서 Job scheduler가 Ready 상태로 넘어올 수 있도록 admit해주는 역할을 한다. 즉, Job scheduler는 New 상태의 프로세스 중 어떤 것을 Ready Queue로 보낼지를 결정한다.

또, Degree of multiprogramming(메모리에 올라가는 프로세스의 수)을 제어한다. 메모리에 너무 많은 프로그램이 올라가면 컴퓨터 성능이 떨어진다. 반면, 너무 적은 프로그램이 올라가면 하나의 프로그램이 다른 작업을 하는 동안 넘겨 받을 CPU가 없는 문제가 생긴다. 따라서 메모리에 올라가는 프로세스 수를 제어하는 것이 중요하다.

cf. 하지만 보통 우리가 사용하는 시스템에는 이런 장기스케줄러가 없다고 한다.

중기 스케줄러 (Medium-term scheduler, Swapper)

앞서 장기 스케줄러에서 보통 우리가 사용하는 시스템에는 장기 스케줄러가 존재하지 않는다고 했다. 대신 우리가 사용하는 시스템은 중기 스케줄러를 이용해 메모리에 올라갈 프로세스의 수를 제어한다. 장기 스케줄러가 존재하지 않는 현재의 시스템은 무조건 프로세스에 메모리를 주게 된다. 이는 너무 많은 프로그램이 동시에 올라가는 문제를 발생시킨다. 따라서 중기 스케줄러, 스와퍼가 일부 프로그램을 골라 메모리에 통째로 쫓아낸다. 이를 통해 메모리에 올라가 있는 프로세스의 수를 조절하여 시스템 성능을 개선한다.

이런 중기 스케줄러의 도입으로 프로세스의 상태가 조금 변경된다. 변경된 프로세스의 상태를 살펴보자.

프로세스의 상태 (Changed By Swapper)

Suspended 상태가 추가되었다. 중기 스케줄러로 인해 메모리를 통째로 뺏긴 프로세스의 상태를 설명하기 위함이다. 프로세스에게서 메모리를 뺏기면 하던 일을 멈추고 정지 상태가 된다. 이를 프로세스가 메모리에서 디스크로 Swap Out된 상태라고 한다.

Blocked

자신이 요청한 일을 오래 기다리고 있는 상태, event 만족 시 ready가 된다.

Suspended

외부에서 정지시켜놓은 상태. 외부에서 다시 재개를 시켜줘야 active 상태가 될 수 있다.

Blocked 상태에서 Suspended가 되었는지, Ready에서 Suspended가 되었는지에 따라 두 가지로 구분된다. Suspended blocked에서 I/O와 같은 오래 걸리는 작업이 완료되면 Suspended Ready로 바뀔 수는 있지만 CPU를 활용해서는 아무것도 할 수 없다.

 

 

 

Thread

Thread(스레드)란, 프로세스 내부에서 실행되는 작은 작업의 단위를 말한다.

 

배경

프로세스를 만들 때마다 그 프로세스만의 주소 공간이 만들어진다. 그리고 그 프로세스를 관리하기 위해 운영 체제 내부에 PCB를 둔다. 동일한 일을 하는 여러 프로세스가 있다고 가정하면, 각각의 프로세스마다 별도의 주소가 만들어져 메모리가 낭비된다. 같은 일을 하는 프로세스를 여러개 만들면서 메모리를 효율적으로 사용하고 싶다면, 주소공간은 하나만 띄워놓고 프로세스마다 다른 부분을 실행시켜주면 된다. 이를 위해 하나의 주소 공간에 CPU 수행 정보에 관련한 것(Program Counter 등)들을 여러 개 두는 것이다.

즉, 하나의 프로세스에 CPU 수행 단위만 여러 개 두고 있는 것을 스레드라고 한다. 하나의 프로세스는 하나의 태스크를 가지되, 여러 개의 스레드를 가질 수 있다.

 

구성

(출처 : https://core.ewha.ac.kr/publicview/C0101020140321141759959993?vmode=f)

 

Thread 마다 현재 레지스터에 어떤 값을 넣고, Program Counter가 코드의 어느 부분을 가리키면서 실행하고 있는지에 대한 정보를 별도로 유지한다. 따라서 위 사진과 같이 프로세스 하나에 공유 가능한 메모리 주소 공간, 프로세스 상태도, 각종 자원들은 공유하되, CPU 수행과 관련된 Program Counter, Register, Stack들은 별도로 가진다.

 

 

Multi-Threaded Process 장점

(출처 : Operating System Concepts - Abraham Silberschatz)

 

1. 빠른 응답성 제공

하나의 서버 스레드가 blocked인 상태에서도, 동일 태스크 태의 다른 스레드가 실행되어 빠른 처리를 할 수 있다. 예를 들어 웹 브라우저를 실행한다면, 네트워크를 통해 웹 페이지를 읽어오게 된다. 이 과정은 I/O 작업이므로 읽어오는 시간이 오래걸려 그 동안 웹 브라우저는 Blocked 상태가 되어 웹 페이지를 모두 읽어오기 전까지 화면에 아무것도 보여줄 수 없게 된다. 만약 웹 브라우저를 여러 개의 스레드를 이용해 프로그램을 만든다면 어떻게 될까? 하나의 스레드가 웹 서버에서 페이지의 그림을 블러오는 동안 프로레스를 Blocked 시키지 않고 다른 스레드가 빨리 읽어온 텍스트를 홈페이지에 먼저 표시할 수 있다. 즉, 빠른 응답성을 제공할 수 있는 것이다.

 

2. 자원 공유

동일한 프로세스가 하나 만들어지면 그 프로세스 만의 독자적인 만들어야하므로 메모리를 낭비한다. 멀티 쓰레드는 자원을 공유하여 효율적으로 자원을 관리한다.

 

3. 경제성

효율적이라는 의미이다. 프로세스를 새로 하나 만드는 것보다 프로세스 내에 스레드를 추가하는 것이 overhead가 작다. 또 문맥 교환 시에도 스레드 간의 스위치는 동일한 주소를 쓰고 있어 대부분의 문맥은 그대로 사용하기에 overhead가 작다.

 

4. Utilization of MP Architectures

여러개의 CPU(멀티 프로세스)를 사용할 때의 장점이다. 프로세스는 하나지만 그 안에 스레드가 여러개 있으면 각각의 스레드가 서로 다른 CPU에서 병렬적인 수행이 가능해 빠른 결과를 얻는다.