Chapter 03. 프로세스와 스레드
누워서 보는 운영체제 이야기 - 김주균 교수님
# 3.1 프로세스란 무엇인가?
▶ Job: 시스템에서 처리해줘야 할 일거리 하나의 단위 = process(Task, Thread) ≠ processor(H/W): 일을 처리할 수 있는 기능을 가짐 ex) CPU
▶ 프로세서의 정의
- 수행 중인 프로그램 (A program in execution)
- 수행 중(in execution): 어떤 일을 함을 나타내는 프로그램과 이때 필요한 값들을 저장하고 있는 처리기 레지스터, 스택 등의 데이터와 함께, 어느 정도 진행되었는지를 나타내는 PC 값 등으로 표현되어, 커널에 등록되어 있다는 것을 의미
▶ 프로그램과 데이터를 기본으로 정상적인 실행을 위해 필요한 환경을 시스템으로부터 부여받은 능동적인 존재
1) 프로세스 제어 블록 (Process Control Block, PCB)
- 프로세스에 대한 모든 정보를 가진 자료구조
- 프로세스 생성 시에 만들어 짐
- PCB들은 메모리에 상주
- PCB에 저장되는 정보들
프로세스 번호 (Process Identification Number) |
프로세스를 구별하기 위한 고유 번호 |
프로세스의 상태 (Status) |
준비, 실행, 대기, 보류 등의 상태 |
프로세스 우선순위 (Priority) |
스케줄링 할 때 사용되는 우선 순위 |
프로그램 카운터 (Program Counter, PC) |
다음에 실행될 명령어의 주소 값 |
메모리 포인터 | 프로그램과 데이터가 저장되어 있는 메모리 블록 위치와 공유되는 메모리 블록들에 대한 포인터 |
문맥 데이터 | 문맥 교환 시에 CPU 레지스터 값들을 저장하는 영역 |
할당받은 자원들에 대한 목록 | 개방(Open)한 파일 등 할당 받은 자원들의 정보 |
계정 정보 (Accounting Information) |
CPU를 사용한 시간 등의 정보 |
입출력 정보 | 진행 중인 입출력 요구 등의 정보 |
2) 프로세스의 상태(Process State)와 변화
▶ 프로세스가 만들어져 시스템에 존재하는 동안 여러 가지 사건들에 의해 일련의 상태 변화를 거침
▶ 생성(Created) 상태
- 사용자가 요청한 작업이 커널에 등록되고 PCB가 만들어져 프로세스가 만들어진 다음, 준비나 보류 준비 상태로 되기 위해 잠시 거치는 상태
- 프로세스를 생성한 후, 메모리 공간을 검사하여 충분한 공간이 있으면 메모리를 할당하면서 준비 상태로 바꾸어주고, 그렇지 못할 경우 보류 준비 상태
▶ 준비(Ready) 상태
- CPU를 할당 받기 위해 기다리고 있는 상태
- CPU만 주어지면 바로 실행할 준비가 되어 있는 상태
- 준비 상태의 여러 프로세스를 저장하기 위해 큐(준비 큐)를 사용
- 준비 상태의 프로세스들은 순서에 따라 CPU를 할당받으면 실행 상태가 됨 → 이때 순서를 정하는 것을 CPU 스케줄링이라 함
▶ 실행 (Running) 상태
- CPU를 할당받아 실행 중인 상태
- CPU를 할당하는 것을 디스패치(Dispatch)라고 함
- 실행 상태의 프로세스는 CPU 스케줄링 정책에 의해 CPU를 뺏길 수 있으며, 이 경우 준비 상태로 바뀌게 됨
- 특히, 시간 할당량(time quantum)이 소진되어 뺏길 때를 시간 종료(time out)이라 함
- 또 다른 경우로, 실행 상태의 프로세스가 입출력이 필요하게 되어 시스템 호출을 하면 입출력 처리가 끝날 때까지 대기 상태로 바뀌게 되고, CPU는 준비 상태의 프로세스들 중에서 하나를 선택하여 그 프로세스에게 할당됨
▶ 대기 (Blocked) 상태
- 프로세스가 실행되다가 입출력 처리를 요청하거나, 바로 확보될 수 없는 자원을 요청하면 CPU를 양도하고 요청한 일이 완료되기를 기다리면서 대기하는 상태
- 대기 상태의 프로세스들 역시 이들의 관리를 위해 큐가 사용됨
- 요청한 일이 완료되면 준비 상태로 이동
▶ 종료 (Terminated) 상태
- 프로세스가 종료될 때 아주 잠시 거치는 상태
- 프로세스에 할당되었던 모든 자원들이 회수되고, PCB만 커널에 남아있는 상태
- 운영체제가 시스템에 남겨져 있는 이 프로세스의 흔적들을 최종 정리 후 PCB를 삭제하면 프로세스는 완전히 사라짐
▶ 준비, 실행, 대기 상태들을 활성 상태(active state)라고 부름
- 활성 상태: 실행 될 프로그램과 데이터 등을 위해 메모리 공간을 부여받았음을 의미
- multiprogramming degree: 메모리에 올라가 있는 세 state(준비, 실행, 대기)에 있는 프로세스의 개수
- 메모리가 부족하거나 다른 이유에 의해 시스템은 활성 상태의 프로세스로부터 메모리를 회수하는 경우가 있는데 이때를 보류(suspension) 시킨다고 하며 이에 반대되는 과정을 재개(resume)이라고 함
▶ 보류 상태는 프로세스가 메모리 공간을 뺏기고 디스크로 나가야 하는걸 말함. 이것을 스왑 되어 나간다(swapped out)라고 하고, 나중에 다시 메모리에 들어오면 스왑 되어 들어온다(swapped in)라 부르며, 두 경우를 통틀어 스와핑(swapping)이라 부름
- 보류 대기에서 보류 준비로 가지 않고 바로 대기 상태가 되는 경우: 실행 중인 프로세스가 종료되어 메모리에 여유가 생겼음. 이때 대기시켰던 원인이 곧 해소될 것으로 판단되는 프로세스가 보류 대기에 있는데 보류 상태 중인 어떤 프로세스보다 우선순위가 높음. 이 프로세스에게 메모리를 주고 대기 상태로 만드는 것이 결과적으로 더 효과적이라고 생각한 것. 보류 준비 중인 프로세스를 준비 상태로 만들어준다면 보류 대기에 있으면서 우선순위가 가장 높은 프로세스 때문에 또 한 번의 스와핑을 겪어야 하는 부담이 발생하므로 이것을 피하고자 하는 것. 즉, 보류 준비에서 보류 대기로 갈 수 없기 때문에 보류 준비가 가득 찬 경우, 보류 준비에 있는 프로세스들 중 하나가 스와핑을 통해 준비로 이동하고 이로 인해 자리가 생기게 되고 보류 대기에서 높은 우선순위를 가지고 있다고 한 프로세스는 보류 준비로 올라오게 됨. 이때 이 프로세스는 우선순위가 가장 높으므로 또 준비 상태로 올라와야 함. 따라서 총 두 번의 스와핑이 발생하는 상황이 발생하므로, 보류 대기에서 대기로 스와핑을 한 번만 하여 보류 대기에 있으면서 우선순위가 가장 높은 프로세스를 메모리로 올리는 것이 더 효율적이라고 판단하는 것
- 실행 중인 프로세스가 종료되어 CPU가 비게 되었고, 보류 준비에 있는 프로세스가 준비 상태의 프로세스들 보다 높은 경우: 두 가지 방법을 사용할 수 있음. 스와핑을 1번하고 우선순위를 고려하거나 스와핑을 하지 않고 우선순위도 고려하지 않는 것인데, 이 두 방법을 선택하는 기준은 우선순위의 차이가 정해둔 임계값보다 큰지 작은지에 따라 선택하는 것임
▶ 보류 준비 (Suspended Ready) 상태
- 생성된 프로레스가 바로 메모리를 받지 못할 때나, 준비 또는 실행 상태에서 메모리를 잃게 될 때를 위해 필요
- 실행 상태의 프로세스가 CPU를 반납하면서 준비 상태로 바뀔 때 메모리 공간까지 잃어야 하는 경우라면 보류 준비 상태로 바뀌게 됨(Suspended)
- 메모리의 여유가 생기거나 또는, 준비 상태의 프로세스가 전혀 없을 때 대기 상태의 프로세스를 보류 대기로 만들어 메모리 공간이 확보되면 준비 상태로 바뀌게 됨(Resume)
- ex) I/O가 계속 발생하여 많은 프로세스들이 대기 상태로 내려오고 준비에는 아무런 프로세스가 없는 상황(CPU가 놀게 됨)일 때, 새롭게 생성된 프로세스는 대기상태에 있는 어떤 프로세스보다도 우선순위가 높다고 가정함. 가득 찬 대기 상태의 프로세스들로 인해 메모리 공간이 부족할 경우 대기에 있는 프로세스들을 보류 대기로 이동시켜 메모리를 확보하고 생성된 프로세스를 준비 상태로 가져와 CPU가 계속 일을 하도록 할 수 있음
▶ 보류 대기(Suspended Blocked) 상태
- 대기 상태에서 메모리 공간을 잃은 상태
+) 문맥 교환(context switching)
▶ 모드 스위칭(mode switching)
- 인터럽트 처리 전후의 프로세스가 같은 경우 이 경우는 사용자 모드에서 인터럽트 처리를 위해 커널모드로 바뀌고 처리가 끝나면 다시 사용자 모드로 바뀜
- 문맥 교환을 필요한 일의 양이 프로세스 스위칭보다 작음
- ex) 입출력 완료 인터럽트 등
▶ 프로세스 스위칭(process switching)
- 인터럽트 처리 전 후의 프로세스가 달라지는 경우
- ex) 시간 종료 인터럽트, 입출력 요청 등
- 문맥 교환을 필요한 일의 양이 모드 스위칭보다 많음
▶ 일반적으로 프로세스 스위칭을 문맥 교환이라고하고, 모드 스위칭은 그 명칭 그대로 사용
# 3.2 스레드(Thread)란?
▶ ex) 쇼핑 인터넷 사이트에서, 작은 동영상이 한쪽에서 돌아가고, 물건을 사기 위해 입력을 요구하는 부분 그리고 배경 음악이 나옴
▶ 프로세스: 전체적인 하나의 일, 스케줄링의 단위
▶ 한 프로세스에 속한 스레드들은 프로세서가 가지는 자원(주소 공간 포함)을 공유하면서 각자는 자신의 실행 환경(프로그램 카운트, 스택, 레지스터 값들 등)을 가짐
▶ 다중 스레딩: 하나의 프로세스를 다수의 스레드로 만들어 실행하는 것
- 하나의 프로세스 내에 다수의 실행 단위들이 존재하여 작업의 수행에 필요한 자원들을 공유하기 때문에 자원의 생성과 관리가 중복되는 것을 줄일 수 있음
- MS-DOS, UNIX: 다중 스레딩을 지원하지 않음
- Windows, NT, Solaris, OS/2: 지원
다중 프로세스에 단일 스레드: 다중 스레딩을 지원하지 않을 때 주로 사용
다중 프로세스에 다중 스레드: 다중 스레딩을 지원할 때 주로 사용
1) 스레드에 대해 조금 더
▶ 프로세스
- 보호와 자원의 할당 단위
- 즉, 프로세스의 코드와 데이터를 수용하기 위한 주소공간과 CPU, 파일들, 입출력에 사용되는 자원에 대한 보호된 액세스를 보장하기 위한 단위
▶ 스레드들
- 스레드의 상태(실행, 준비 등) 스레드 문맥, 실행 스택, 자신이 속한 프로세스가 가지는 메모리와 자원에 대한 접근 권한을 가짐
사용자 주소 공간: 이때 주소는 메모리에 저장된 data의 위치를 나타냄
사용자 스택: 재귀 호출 시 사용
각 스레드는 자신의 제어 블록과 스택을 가지며 이때 제어 블록은 실행 중의 레지스터 값, 우선순위,
또는 스레드와 관련한 상태 정보 등을 위해 필요한 자료구조임. 이를 이용하여 스레드를 구별하여 control 할 수 있음
▶ 장점
- 스레드를 만들고, 없애고, 이들 간의 스위칭에 소요되는 시간과 비용이 프로세스 단위로 이루어질 때 보다 빠르고 저렴
- 한 프로세스 내의 스레드간의 통신은 메모리와 파일을 공유하기 때문에 커널의 개입이 필요 없음
- 자원은 프로세스 단위로 구성된다는 점을 기억해야 함
2) 스레드의 상태와 동기화(Synchronization)
- 프로세스와 마찬가지로 스레드 역시 실행, 준비, 대기와 같은 상태를 가지며, 다만 보류는 프로세스 레벨의 개념이므로 스레드에서는 필요 없는 상태 → 메모리라는 것은 프로세스 단위로 주어지는 시스템 자원이고 스레드들은 이를 공유하기 때문에 보류라는 개념 X
- 대기는 레지스터 값, 프로그램 카운터, 스택 포인터 등의 보관이 요구되며, 스레드의 종료는 해당 스레드의 레지스터 값들과 스택을 없애게 됨
- 한 프로세스 내의 스레드들은 그 프로세스의 주소 공간과 자원들을 공유하기 때문에 특정 스레드가 변경시킨 내용이 다른 스레드에 바로 영향을 미침
- 주소 공간을 공유한다는 것에 있어서 각 스레드의 write, read 하는 시기가 충돌하지 않으면 괜찮지만, 한 스레드가 수정 중인데 CPU가 그 상황에서 다른 스레드를 택하게 되고 선택된 스레드가 값을 read 한다면 그 값은 올바른 값이 아님
- 오류를 야기 할 수 있는 상호 간의 간섭이나 데이터의 파괴 등을 방지하기 위한 스레드 실행의 동기화가 요구되는데, 이 문제는 프로세스 간의 동기화에서 발생하는 문제 및 해결책과 동일함
3) 스레드의 종류
▶ 사용자 레벨 스레드(User Level Thread)
- 스레드 라이브러리(Library)에 의해 관리
- 스레드와 관련된 모든 행위(Activity)는 사용자 공간에서 이루어지므로 커널은 스레드의 존재를 알지 못함
- 특정 스레드의 실행에서 대기는 자신이 소속된 프로세스의 대기를 초래하며, 당시 실행 중이었던 스레드는 지금은 실제로 실행 중이 아니지만 나중에 CPU가 다시 이 프로세스에게 할당되었을 때 계속 실행해 나갈 수 있도록 해 줌 → 스레드 라이브러리가 기억해주기 때문
- 스레드의 실행 중 해당 프로세스의 시간 초과가 될 경우 커널은 프로세스의 스위칭을 수행하며, 당시 실행 중이던 스레드는 해당 프로세스가 CPU를 다시 받게 되면 다시 실행됨
- 스레드 간의 스위칭 시 운영체제가 정한 스케줄링에 따를 필요가 없음 → 스레드 라이브러리가 스레드끼리 CPU를 어떻게 사용할지 정해줄 것이기 때문
- 응용 별로 독자적인 스케줄링을 할 수 있으며 어떤 운영체제에서도 운영이 가능
- 단점: 특정 스레드의 대기가 자신이 소속된 프로세스 내의 모든 스레드들의 대기를 초래하며 CPU가 프로세스 단위로 할당되기 때문에 다중처리의 환경이 주어진다 해도 스레드 단위의 다중 처리가 되지 못한다는 점
▶ 커널 레벨 스레드(Kernel Level Thread)
- 모든 스레드의 관리를 커널이 하는 경우
- 스케줄링은 커널에 의해 스레드 단위로 이루어지므로 사용자 레벨 스레드 때의 단점을 극복할 수 있음
- 1. 다중 처리 환경일 경우 한 프로세스 내의 다수 스레드는 각각 처리기를 할당받아 병렬(Parallel) 실행이 가능
- 2. 한 스레드의 대기 시, 같은 프로세스에 속한 다른 스레드로 스위칭이 가능
- 3. 같은 프로세스에 속한 스레드 간의 스위칭에도 커널의 개입이 필요 → 커널이 개입하는 시간만큼 O/S가 돌아야 하기 때문에 단점이라면 단점일 수 있음
RPC: 원격 프로시저 호출(Remote Procedure Call)
(a): 유저레벨 - 한 스레드가 blocked 되면 프로세스 전체가 blocked 됨
(b): 커널레벨 - 한 스레드가 blocked 되면 다른 스레드가 실행됨
+) 커널 레벨의 경우, 단일처리 시스템의 경우에도 스레드를 만드는 것이 프로세스를 만드는 것보다
시간과 비용면에서 이롭다는 것 외에 응용에 따라 전체 실행 시간도 단축할 수 있다는 장점이 있음
'Study > Computer&Operating System' 카테고리의 다른 글
[OS] Chapter 06. 교착 상태(Deadlock) (0) | 2022.05.07 |
---|---|
[OS] Chapter 05. 병행 프로세스와 동기화 (0) | 2022.04.16 |
[OS] Chapter 04. CPU 스케줄링 (0) | 2022.04.15 |
[OS] Chapter 02. 들어가기 전에 (0) | 2022.04.14 |
[OS] Chapter 01. OS? Oh Yes! (0) | 2022.04.14 |