학사 나부랭이

Operating System - Process & Thread 본문

Dot-Gabi/Operating System

Operating System - Process & Thread

태양왕 해킹 (14세) 2021. 4. 1. 20:50

Process

 프로그램은 파일 시스템에 존재하는 실행 파일이고 프로세스는 컴퓨터 상에 수행 중인 프로그램이에요. 실행을 위해 커널에 등록되어있고 CPU 레지스터, Program Counter 값 등의 커널에 등록된 것들을 모두 합친, 즉 프로그램 코드와 그 코드에 연계된 데이터의 집합이에요.

프로세스는 아래와 같은 구성요소를 가져요.

 

PID(프로세스 식별 번호)

프로세스의 유일한 식별자이며 정수 번호예요.

상태

준비, 실행, 대기, 보류 등의 상태를 나타내요.

우선순위

스케줄링을 할 때 사용되는 다른 프로세스들과의 상대적인 우선순위 수준을 나타내요.

Program Counter(프로그램 계수 計数)

프로그램에서 다음에 수행될 명령어의 주소 값을 가지고 있어요.

메모리 포인터

프로그램과 데이터가 저장되어있는 메모리 블록 위치와 공유된 메모리 블록에 대한 포인터를 포함해요.

Context data(문맥 데이터)

Context switching(문맥 교환) 시에 CPU 레지스터 값을 저장하는 영역이에요.

할당받은 자원 목록

연(Open) 파일 등 할당받은 자원의 정보예요.

계정 정보

CPU를 사용한 시간, CPU 시간 할당량(time quantum) 등을 포함해요.

입출력 정보

진행 중인 입출력 요청, 프로세스에 할당된 입출력 장치 등을 포함해요.

 

이들은 Process Control Block(프로세스 제어 블록)이라는 데이터 구조에 저장되며 프로세스가 하나 만들어지는 것은 곧 그 프로세스에 대한 모든 것을 표현하는 PCB 하나가 만들어진다는 말과 같아요. 운영체제가 프로세스를 관리하는 것은 해당 PCB에 대해 다양한 작업을 한다는 것이며 이는 매우 빈번히 일어나는 일이라서 기본적으로 PCB는 메모리에 저장되어요.

 

Context Switching(문맥 교환)

 현재까지 하던 작업에서 잠시 다른 작업을 해야 할 때, 현재까지 한 작업의 상태를 다른 곳에 보관했다가 다시 불러오면 이전의 작업을 그대로 진행할 수 있겠죠? 여기서 CPU가 수행하던 프로세스의 상태 정보(현재 상태)를 포함한 CPU 레지스터들의 값을 context라 하는데 이는 PCB의 전부 혹은 일부분을 일컬어요.

 

Process State Translation

 프로세스가 만들어져 시스템에 존재하는 동안 여러 사건에 의해 상태를 변해가요. 이런 상태는 시스템마다 조금씩 다르게 정의되지만 우리는 Seven-State-Model을 보려고 해요.

New

 Job이 커널에 등록된 상태, 실행 가능한 프로세스 풀에는 포함되어있지 않은 상태예요. PCB가 생성되어도 메모리에 적재되지 않은 상태예요. 그러니까 프로세스가 만들어졌지만 아직 OS에 의해 Activate 되지 않았어요.

Ready

 프로세스에 CPU가 할당되길 기다리는 상태예요. New에서 admit되었고 CPU를 제외한 다른 자원들은 준비가 완료된, HDD 있던 프로그램을 실행시켜 메모리에 적재는 된 상태예요. 이 Ready 프로세스 중 CPU를 할당받을 프로세스를 고르는 작업이 CPU 스케줄링이며 큐가 사용되어요.

Running

 CPU를 할당받아 실행 중인 상태인데 이 때 CPU를 할당해 주는 것을 dispatch라고 해요. 이 상태의 프로세스는 CPU scheduling 정책에 의해 CPU를 뺏길 수 있고 이 경우 suspend 당해서 ready 상태로 돌아가고 ready 상태에 있던 프로세스 중 하나를 선택해 실행하죠. 특히 CPU 시간 할당량(time quantum)이 소진되어 뺏길 때를 시간 종료(time out)이라 하는데 이 경우 인터럽트를 사용해서 처리되어요.

Blocked

 프로세스가 실행되다가 입출력 처리를 요청하거나 당장 가질 수 없는 자원을 요청하면 CPU를 반납하고(계속 가지고 있어도 진행할 수 없으니까) 요청한 조건을 만족시킬 때까지 대기하는 상태예요. 이 상태에 있는 프로세스들 역시 큐를 이용해 관리되어요. 이후 조건이 만족되면 다시 Running로 가기 위해 ready 상태로 바뀌며 ready 큐에 들어가요.

Suspended Ready/Suspended Blocked

 메모리 공간의 여유가 없으면 운영체제가 프로세스에게 할당한 메모리를 회수해도 문제되지 않을 프로세스들을 골라 Suspend(보류)시켜 메모리 공간을 확보해요. 예를 들어 메모리에 올라온 프로세스들이 전부 입출력 요청을 해서 CPU가 쉬고 있을 때, 새로운 프로세스를 받아들여 CPU를 할당시키려면 입출력 대기 순번이 낮은 프로세스를 잠시 보류시켜야 하겠죠? 여기서 보류될 때 메모리 공간을 뺏기고 HDD로 나가는 것이 swapped out, 다시 메모리로 돌아오는 것을 swapped in이라고 하고 이 둘을 합쳐 swapping(어맛! 망측해라...)이라고 해요.

S.ready

 생성된 프로세스가 바로 메모리를 받지 못했거나 Ready || running 상태에서 메모리를 잃게 될 때를 위해 있어요. 실행 상태의 프로세스가 CPU를 반납하며 ready 상태로 바뀔 때 메모리 공간까지 잃어야 하는 경우라면 S.ready 상태로 suspend 당해요. 그리고 Ready 상태의 프로세스가 없을 때 CPU를 쉬게 하지 않기 위해 blocked 상태의 프로세스를 S.blocked으로 만들든지 프로세스가 끝나서 메모리 공간이 확보되면 ready로 activate 되죠.

S.blocked

 프로세스가 Blocked 상태이다가 메모리 공간을 잃은 상태예요. ready를 S.ready로 만드는 경우 위의 Ready 상태의 프로세스가 없어서 뿐만 아니라 메모리 여유 공간을 더 확보하기 위해서도 해요.

Exit

 프로세스가 종료될 때 잠시 거치는 상태예요. 이 상태의 프로세스는 할당된 모든 자원들이 반납되어 PCB만 커널에 남아있는 상태예요. 운영체제가 시스템에 남겨있는 이 프로세스의 흔적을 정리한 후 PCB마저 삭제하면 프로세스가 완전히 사라지게 되죠.

 

 여기서 blocked 상태는 CPU를 준다고 해도 실행 가능한 상태도 아닌데 S.blocked 상태가 S.ready로 가지 않고 바로 blocked 상태로 되는 경우가 필요할까요?

실행 중인 프로세스가 종료되어 메모리에 프로세스 하나 만큼의 여유가 생겼고 곧 요구 조건을 만족시킬 프로세스 P1이 S.blocked에 있으며 P1이 S.blocked, S.ready의 다른 모든 프로세스보다 우선순위가 높을 때, P1에게 스왑 인 시켜 바로 blocked 상태로 만드는 게 S.ready인 프로세스 P2를 ready 상태로 스왑 인 하고 곧 스왑 인 할 P1으로 인해 다시 P2를 스왑 아웃하는 것보다 효율적이죠.

 

Thread

 

 프로세스는 하는 일은 각각 다르지만 서로 관련 있는 작은 일들이 모여 되어요(成りあがる). 이때 작은 일 하나하나를 Thread라고 하는데 여기서 프로세스는 할당된 자원의 소유자로서, 스레드는 스케줄링의 단위로서 존재해요. 한 프로세스에 속한 각각의 스레드는 프로세스가 갖는 자원을 공유하며 각자 자신의 스레드 ID, PC, 레지스터 집합, 스택 등으로 구성되어요.

 

단일 스레드

 하나의 프로세스에서 하나의 스레드를 실행하는 것인데 하나의 레지스터와 스택으로 표현되죠. 다양한 요인이 들어간 데이터 통계 분석 연산에서는 다중 스레드가 더 적합하지만 빠른 반응 속도를 요구하는 네트워크 서버 프로그램 같은 경우는 단일 스레드가 적합할 수 있어요.

다중 스레드

 하나의 프로세스를 다수의 스레드로 만들어 실행하는데 다중 스레딩을 하면 하나의 프로세스에 다수의 실행 단위가 존재하니 작업 수행에 필요한 자원을 공유해서 자원의 생성과 관리가 중복되는 것을 줄일 수 있고 동시에 하나 이상의 작업을 수행하게 할 수도 있어요.

위의 사진에서 각 스레드는 PCB같은 자신의 제어 블록과 스택을 가져요. 동시에 자신이 속한 프로세스의 상태와 자원들을 공유하죠. 따라서 한 스레드에 의해 메모리의 데이터가 변경되면 다른 스레드들은 변경된 데이터를 사용하게 되어요.

스레드는 프로세스에 비해 아래의 장점들을 가져요.

응답성

 일부 스레드의 처리가 지연되어도 다른 스레드는 작업을 계속할 수 있어요.

자원 공유

  프로세스 간의 통신(IPC)은 커널 개입이 필요할 때도 있지만 스레드 사이의 통신은 메모리와 파일을 공유해서 커널이 개입하지 않아도 돼요.

경제성

 프로세스를 만들기 위해 메모리와 자원을 할당하는 것은 비용이 많이 들지만 스레드는 자신이 속한 프로세스의 자원을 공유해서 스레드를 만들고 없애고 context switching 하는데 드는 비용이 더 저렴해요.

멀티 프로세서 시스템에서 활용

 멀티 프로세서 시스템에서 다중 스레드의 강점이 두드러지는데요. 각 스레드가 다른 CPU에서 병렬로 수행될 수 있기 때문이죠.

 

스레드의 상태와 동기화

 스레드도 Run, ready, block같은 상태를 가지나 suspended 상태는 없어요.

한 프로세스 안의 스레드들은 메모리 공간과 자원을 공유하지만 이는 특정 스레드가 변경시킨 내용이 다른 스레드에게 바로 영향을 미친다는 것도 의미해요. 그러니 오류를 야기할 수 있는 영향이나 데이터 파괴 등을 방지하기 위해 스레드 실행의 동기화가 요구되는데 이 기법들은 링크를 참조해주세요.

 

스레드의 종류

Thread library

 스레드의 생성, 소멸을 위한 코드와 스레드 사이의 메시지나 데이터 전달, 스레드의 스케줄링, 스레드 context 보관, 재저장을 담당해요. 유저 레벨에 있어서 커널이 알 수 없어요.

User level thread

 스레드 라이브러리에 의해 관리되며 스레드와 관련된 모든 행위는 유저 레벨에서 이루어지므로 커널은 이 스레드의 존재를 몰라요. 그래서 커널은 이 스레드들의 행위를 그 스레드가 포함된 프로세스의 행위로 인식해요.

특정 스레드가 run에서 blocked으로 변하면 그 프로세스의 블록을 초래하고 당시 실행 중이던 스레드는 스레드 라이브러리에 의해 실행 중이었다는 것을 표시했다가 다시 프로세스에게 CPU가 할당될 때 계속 실행할 수 있게 해 줘요. 스레드 스위칭에서는 커널의 개입이 필요 없으며 이로 인해 모드 스위칭도 필요 없고 스레드 간의 스위칭은 독자적인 스케줄링을 사용할 수 있으니 어떤 운영체제에도 운영 가능해요. 단점으로는 특정 스레드의 블록이 해당 프로세스 내의 모든 스레드의 블록을 초래하며 CPU가 프로세스 단위로 할당되기에 멀티 프로세서 환경이 주어져도 스레드 단위의 멀티 프로세싱은 적용되지 못해요. 그리고 동기화나 Locking 없이 공유하는 변수가 있을 때 그 변수가 오염될 수 있어요.

Kernel level thread

 모든 스레드의 관리를 커널이 하는 경우예요. 스케줄링은 커널에 의해 스레드 단위로 이루어지니 유저 레벨 스레드의 단점을 극복할 수 있죠. 멀티 프로세서 시스템에서 한 프로세스 내의 스레드는 각각 CPU를 할당받아 병렬 실행을 할 수 있고 한 스레드가 블록되면 같은 프로세스의 다른 스레드로 스위칭할 수 있어요. 그러나 같은 프로세스 안에서 일어나는 스레드 스위칭도 커널이 개입해야 해서 모드 스위칭이 요구되죠.

Multiplexed thread

 n개의 유저 레벨 스레드와 m개의 커널 레벨 스레드(단, n > m)로 이루어지고 사용자는 원하는 수 만큼 스레드를 사용할 수 있어요. 커널은 할당된 하나의 유저 레벨 스레드가 블록 되어도 다른 스레드를 수행할 수 있고 context switching을 많이 하지 않아요.

 

다중 스레드 V.S. SMP

 다중 스레드는 싱글 프로세서 시스템에서도 응용 프로그램과 커널 프로세스를 구축하는데 유용하지만 SMP는 여러 프로세스가 병렬 수행 될 수 있기에 스레드화(化)되지 않은 프로세스들에게도 유용해요. 그러나 이 두 기능은 상호보완적이라 동시에 사용될 때 효과적이죠.

Comments