# 3-1 Process
프로세스의 개념
프로세스
- 실행 중인 프로그램
- 실행 시작하면 독자적인 주소 공간 만듦
- 이 프로세스가 CPU 잡으면 프로그램 카운터라는 레지스터가 이 프로세스의 코드 어느 부분을 가리키고 있고
- 그럼 매순간 인스트럭션(기계어)를 하나씩 읽어 CPU 안으로 불러들이고
- 레지스터 안에 어떤 값을 넣고, 연산 후(= ALU), 그 결과를 레지스터에 저장하거나 바깥의 메모리에 저장하는 방식으로 계속 진행
- 이 프로세스가 어느 시점에 와있는지 규명하는 것
- 프로세스의 현재 상태를 나타내는 데 필요한 모든 것
문맥
- 전체적인 문장 구조를 이해해야 무슨 의미인지 알 수 있음
프로세스 개념에서의 문맥
- 실행부터 종료까지 볼 때 이 프로그램을 어떻게 실행하는지, 어느 시점에 있는지 등 이해 가능
- 특정 시점을 놓고 봤을 때 프로세스가 어디까지 수행했는지
PC
- Program Counter, 프로그램 카운터
- 이게 어딜 가리키고 있는지, 코드의 어느 부분까지 실행했는지 파악
Code
- 메모리에 어떤 내용을 담고 있는가
Stack
- 함수 등 실행했다면 쌓는 공간
Data
- 변수 등 값을 바꾸는 공간
그림 상의 R1, …
- 레지스터
- 어떤 값을 넣고 어떤 인스트럭션을 실행했는가
CPU 수행 상태 나타내는 프로세스의 문맥
- 프로세스는 CPU를 잡고 매순간 인스트럭션 실행함
- 현재 시점에 프로세스가 인스트럭션을 어디까지 실행됐는지 알기 위해 레지스터에 어떤 값을 넣고, 프로그램 카운터가 어디를 가리키고 있는지 등을 파악하는 개념
프로세스 주소 공간
- 어떤 내용이 들어있는가
프로세스 관련 커널 자료구조
PCB
- 운영체제가 프로세스를 관리
- 프로세스가 하나 시작될 때마다 운영체제는 그 프로세스를 관리하기 위해 자신의 데이터 영역에 자료구조를 둠
- PCB에 CPU, 메모리를 얼마나 줘야 할지, 얘가 나쁜 짓을 하는지 고려함
Kernel stack
- 각 프로세스가 자기 자신의 코드를 실행할 때 함수호출이 이루어지면, 본인 스택에 함수 호출 후 리턴하고, 관련 정보를 쌓아둠
- 근데 프로세스가 실행하다 본인이 할 수 없는 일을 운영체제에 대신 요청(시스템콜)하면, 프로그램 카운터가 커널의 어딘가를 가리키며 실행
- 커널도 함수로 구성되어 있기에 커널에서 함수호출 이루어지면 스택에 관련 정보 쌓음
- 커널 = 여러 프로세스들이 공유하는 코드라 할 수 있음
- 어떤 프로세스 간에 운영체제에 요청하면 커널 코드를 실행함
- 커널이 누구의 부탁을 받고 실행하는지는 매번 다름
- 커널에서 함수호출이 이루어지면 스택에 정보 쌓고, 그때 어떤 프로세스가 커널을 호출했는지에 따라 스택을 별도로 둠
- 이렇게 해야 정보가 꼬이는 등의 문제 방지
- 프로세스의 현재 상태 규명 위해 유저 스텍 말고 커널 스택에 쌓인 정보 필요
- 이런 정보 알면 프로세스가 현재 어떤 상태인지 규명 가능
- 프로세서 혼자 실행하면 우리가 이런 걸 알 필요 없음
- 근데 현대 컴퓨터 시스템에서는 타임쉐어링, 멀티태스킹이 번갈아 실행되기에, 하나의 시스템이 CPU 잡고 실행하다 다른 프로세스에 CPU 넘어감
- 그럼 현재 프로세스가 레지스터에 어떤 값을 넣고 실행 시, 이걸 백업해두지 않으면 = 프로세스의 현재 문맥을 알고 있지 않으면, 다음 CPU 에서 이 프로세스를 잡을 때 어느 부분부터 실행해야 할지 모름
- 어느 시점까지 실행했는지를 정확히 알고 있어야, 그 다음부터 인스트럭션을 실행할 수 있음
프로세스의 상태
Running
- 컴퓨터 안에 CPU는 하나(이 강의 기준)
- CPU를 잡고, 인스트럭션을 실행하고 있는 프로세스는 매순간 하나일 거임, 이때의 프로세스 상태 = running
Ready
- CPU가 하나이기에 너도나도 CPU를 쓰겠다 줄 서 있으나 본인 차례를 기다려야 하는 프로세스들의 상태 = ready
- 프로그램이 실행되려면 CPU가 디스크에 접근 못하니, 물리적 메모리에 올라오고 CPU를 얻었을 때 인스트럭션 실행 가능
- 프로세스 실행 준비가 다 끝나 있고 CPU만 얻으면 내가 인스트럭션을 열심히 실행할 수 있다 = ready
- Ready 상태의 프로세스들이 CPU를 잡았다 놨다 하면서 타임쉐어링을 구현하고 있음
Blocked, wait, sleep
- CPU를 줘봤자 인스트럭션을 실행 못하거나, 오래 걸리는 I/O 작업 등의 결과를 디스크에서 읽어와야 다음 작업 실행 가능한 프로세스의 상태 = blocked, wait, sleep
- 어떤 프로그램의 전체 주소 공간을 물리적 메모리에 올려두고 실행하지 않음, Why? 여럿이 동시에 써야하기 때문
- 어떤 프로그램의 코드 실행 시 코드 부분이 메모리에 올라와있지 않고 디스크에 내려가있으면, 당장 CPU 줘봤자 실행 불가 = 프로세스 blocked 상태
- 프로세스 자신이 요청한 이벤트 등을 하고 있기에, 이게 만족되기 전까진 CPU 줘봤자 일 못함
New
프로세스가 막 생성 중(실행 전 단계)
Terminated
프로세스 자체가 끝나면 이를 정리하는 작업이 필요한데 그 상태를 말함
CPU
- 빠르고 여러 자원이 공유
- 하나의 프로세스가 CPU에서 running 하다 timer interrupt 들어오면 CPU 뺏기고 맨 뒤로 가서 줄 서고, 그 다음 프로세스가 CPU 얻고
- CPU 에서 running 되다가 디스크에서 뭔가 읽어와야 하면 이 프로세스의 상태는 running ➡️ blocked 로 되고, 디스크의 서비스를 받는 queue 로 가서 줄 섬
- 그럼 디바이스 컨트롤러의 지휘 하에 순차적으로 진행되고, 이 작업이 끝나면 컨트롤러가 CPU에 인터럽트 걸고 I/O 작업이 끝났다는 걸 알려줌
- CPU는 인터럽트가 들어왔으니, 하던 작업 멈추고(라인 단위), CPU 제어권이 운영체제 커널에게 넘어감
- 운영체제 커널은 I/O 요청했던 프로세스의 I/O 작업이 끝났으니, 그 프로세스의 메모리 영역에 I/O 작업 결과물에 해당하는 데이터를 넘겨주거나, blocked 된 프로세스의 상태를 ready 로 바꾸고 CPU를 사용할 수 있는 자격을 줘서 줄 서 있게 해줌
자원
- 하드웨어 자원도 있으나
- 소프트웨어 자원도 있음 = 공유데이터
- 여러 프로세스가 공유데이터에 동시 접근하면, 하나의 프로세스가 접근하다 다른 프로세스가 CPU 점유하며 그 공유데이터를 쓰게 되는 경우가 발생하면서, 데이터 정합성이 깨질 수 있음
- 즉, 다른 프로세스가 접근하려 할 때 이를 막아주는 게 필요
- Resource queue 에 줄 서서 기다려야 함
- 오래 기다리는 작업이 필요하면 프로세스는 blocked 되고, 그 이유가 공유데이터 때문인지, 디스크 때문인지, I/O 작업 때문인지 등 확인 후 ➡️ 그 작업이 해당하는 종류의 Queue 로 가서 줄을 선 다음 ➡️ 끝나면 ready queue 로 넘어와 CPU 점유 대기
- 모든 자원이 놀지 않고 각자의 일을 할 수 있게 배분해주는 것이 중요
- Queue = 운영체제 커널이 본인의 데이터 영역에 자료구조로 큐를 만들고 프로세스 상태를 바꿔가며 ready 상태에게 CPU 주고, blocked된 프로세스에겐 안 줌
- 운영체제 커널이 각 프로세스마다 그 프로세스 관련 정보(관리 목적)를 두기 위한 PCB 가 있음
프로세스 상태도
New
- 프로세스 생성
Ready
- CPU만 얻으면 실행 가능
- 여기에선 인스트럭션 실행에 필요한 최소한의 메모리는 가지고 있어야
Running
- CPU를 얻어 실행
Blocked
- 자진해서 CPU를 내어줌(I/O 작업 등 필요하니)
Timer interrupt
- 나는 CPU를 계속 쓰고 싶지만 CPU 사용시간을 나눠 써야함
- 나에게 할당된 시간을 뺏기면,다시 줄 서야 하는 경우
- CPU 오래 써야 하는 프로세스는 CPU를 얻었다 뺐겼다 반복
Terminated
- 본인 역할 다 끝날 때
Process Control Block
- 운영체제 커널이 각 프로세스마다 그 프로세스 관련 정보(관리 위한)를 두기 위한 PCB가 있음
- 프로세스 하나 당 PCB가 있음
- 프로세스 상태를 나타내고, 프로세스 ID 로 구별
- 프로세스에게 CPU 주기 위한 스케줄링 정보가 있음
라운드 로빙
- CPU 스케줄링 방식
- 먼저 온 순서대로 처리하는 게 아니고, 우선순위가 제일 높은 애에게 CPU 넘겨주는 등의 방식
문맥 교환
- 굉장히 중요한 개념
- 어떤 프로세스가 CPU 장악 후 계속 쓰는 게 아니라, 짧은 간격으로 CPU를 쓰다 뺏겼다 반복
- CPU를 다시 받아오면 뺏긴 시점을 기억했다 거기서부터 다시 시작하는 거임
- 사용자 프로세스 하나로부터 다른 프로세스로 넘어가는 과정을 일컫음
- 어떤 프로세스가 실행 중이면
- 프로그램 카운터가 어딘가를 가리키고 있고
- 레지스터에 어떤 값 넣어 실행하고 있고
- 메모리 맵에 메모리 위치 정보가 있고
- 이렇게 실행하다 타이머 인터럽트로 CPU 뺏겼다 다시 실행 재개하려면
- 레지스터에 저장된 값이나 메모리맵이랑 프로그램 카운터 정보도 모두 PCB에 저장해둠
- CPU 내의 레지스터 등은 하드웨어 자체를 나타냄
- 문맥 교환될 때는 위 정보들을 저장하는 공간인 커널의 프로세스 PCB에 저장
- CPU 를 다시 받은 프로세스도 실행을 재개하기 위해 문맥을 찾아야 하는데, 이를 PCB에서 찾아서 하드웨어로 복원시킴
메모리 맵
- 메모리 위치 정보
시스템콜
- 프로세스가 본인이 필요해서 운영체제에게 뭔가 요청할 때
인터럽트
- 하드웨어 인터럽트를 말함
- 컨트롤러 같은 장치가 CPU에 정보 전달할 목적으로 인터럽트 걺
문맥 교환
- 사용자 프로세스 하나로부터 또다른 사용자 프로세스로 CPU가 넘어가는 과정
- 시스템콜이나 인터럽트 걸면 사용자 프로세스로부터 운영체제 커널로 CPU가 넘어가는 것이기에, 문맥 교환이 아님
- 근데 사용자 프로세스가 인터럽트 걸어서 운영체제로 CPU 넘어간 후, 운영체제가 또다른 사용자 프로세스로 CPU를 넘기는 건 문맥 교환이 맞음
ISR
- Interrupt Service Routine
타이머 인터럽트
- CPU를 다른 프로세스에게 넘기기 위한 의도를 가진 인터럽트
- 타이머 인터럽트가 들어오면 또다른 사용자 프로세스에게 CPU를 넘김 = 문맥 교환
- A 프로세스에서 B 프로세스로 문맥 교환을 해야 하는 경우 오버헤드가 큼
- Why? 문맥 교환이 일어나면 캐시 메모리를 다 지워야 하기 때문(cache memory flush)
- 근데 A 프로세스 작업하다 ➡️ 커널로 갔다 ➡️ 다시 A 프로세스로 돌아오면 CPU context 정도만 가지고 있다 save 함
프로세스를 스케줄링하기 위한 큐
Ready Queue와 다양한 Device Queue
- 실제 큐에서 어떻게 관리되고 있는지
- 디바이스마다 큐가 있고, 큐 헤드와 테일로 구성
- 큐에는 프로세스를 줄 세운다고 하는데, 운영체제가 프로세스를 관리하는 자료구조, 즉 PCB를 관리
- PCB에는 포인터가 있는데 그걸 이용해 queue 내의 프로세스들이 연결되는 것(그림의 화살표)
프로세스 스케줄링 큐의 모습
- 프로그램이 시작되면 ready queue 에 줄을 서고
- 자기 차례가 되면 CPU를 얻고
- CPU를 점유할 할당 시간이 끝나면
- 다시 ready queue 에 와서 줄 서야 하고
- 또 CPU를 점유하다 오래 걸리는 작업 수행해야 하면
- 그 작업에 해당하는 queue 에 가서 줄 서다 작업 수행하고
- 그 오래 걸린 작업이 끝나면 CPU 다시 점유해서 마저 실행 후
- 작업이 다 끝나면 빠져나가기
- 근데 그림이 좀 잘못됐대
- 인터럽트 발생 시 CPU를 빼앗기는 것이기에 ready 상태로 그려져 있긴 한데, 정확히는 ready 로 넘어가는 건 아님(다음 강의에서 다룸)
- 프로세스가 CPU 잡고 있다가 자식 프로세스를 만들 수 있음(프로세스 생성 관련 다음 강의에서 다)
스케줄러
- 순서를 정해줌
- 시스탬 내의 스케줄러 = 각각의 자원 별로 어떤 일을 할지, 얼마 동안 실행시킬지 등을 정함
단기 스케줄러
- CPU 스케줄러
- 굉장히 짧은 시간 단위로 스케줄이 이루어짐
- 스케줄이 이루어지는 단위가 밀리세컨드
- 굉장히 자주 이루어짐
- 다음에 어떤 프로세스에 CPU 줄지 정함
장기 스케줄러
- 단기 스케줄러의 반대
- 어떤 프로세스에게 줄지 결정
- = Job 스케줄러
- 프로세스가 시작돼 new 상태였다가 ready 로 넘어가는 과정에서 어떤 일이 일어나느냐, 뭘 admitted 하느냐, 메모리에 올라가는 걸 admit 하는 거임
- 처음 프로세스가 시작된 후 메모리를 얻지 못하면 아무 일도 발생하지 않기에, 메모리에 올라가는 걸 허락해주면 그때부터 작업 시작할 수 있음
- 이 스케줄러가 프로세스에 메모리를 줄지 안 줄지를 결정함
- Degree of multi-programming – 메모리에 여러 프로그램이 동시에 올라갈 때 총 몇 개의 프로그램이 올라가 있는지를 나타내는 것
- 메모리에 올라가는 프로세스의 수를 제어함
- 메모리에 너무 많은 프로그램이 동시에 올라가면 컴퓨터 전체의 성능이 안 좋아짐 / 너무 적게 올라가도 안 좋아짐 = 그 프로그램이 CPU 쓰다가 I/O 하러 가면 CPU는 놀게 됨
중기 스케줄러
- 지금 우리가 사용하는 시스템은 degree of multi-programming 을 어떻게 조절할까? 장기 스케줄러 역할 없이 프로그램이 시작되자마자 바로 ready 로 올라가거든
- 바로 ready 로 올라가면 메모리에 너무 많은 프로그램이 올라가 문제될 수 있는데, 이제 중기 스케줄러가 이를 조절해줌 = swapper
- 스와퍼가 일부 프로그램을 골라 메모리에서 통째로 쫓아냄, 이렇게 degree of multi-programming 수를 조절해 전체 시스템 성능을 향상시킴
- 예전엔 장기 스케줄러로 초반부터 메모리에 올라갈 것들을 정해줬지만, 요즘은 시작 때 무조건 다 올려준 다음, 너무 많은 프로그램이 메모리에 있다 싶으면 몇 개는 쫓아내는 시스템
Implementation of Threads
프로세스의 상태
- 중기 스케줄러로 인해 프로세스 상태가 추가됨
- 중기 스케줄러로 인해 메모리를 통째로 뺏긴 경우, 그 상태를 표현할 길이 없어서 생겨남
- CPU 관점에서의 상태 – running, ready, blocked
- Running = CPU 잡고 있는 상태
- Blocked = 프로그램 본인이 CPU를 잡고 일을 하다가 I/O 작업 같은, 오래 걸리는 작업 위해 다른 곳에서 작업하는 상황
- Suspended = CPU 뿐만 아니라 외부에서 이 프로세스를 강제로 정지시켜놓은 상태, 메모리에서 쫓겨나 디스크로 swap out 된 상태
- Break key 누르면 프로세스가 끝난 건 아닌데 잠깐 정지시킬 수 있음, 그럴 때도 프로세스는 메모리를 통째 잃고 suspended 상태 됨
- 사람이 잠시 정지된 프로그램을 재개시켜야 suspended 상태에서 벗어날 수 있음
프로세스 상태도
- 여기서의 그림은 사용자 프로그램의 상태도를 의미하지, 운영체제의 상태도를 말하는 게 아님
User mode
- 프로세스가 CPU 가지고 있으면서 본인 코드 실행시킬 때
Monitor mode
- 본인이 어떤 일을 할 수 없어 운영체제에 요청해 시스템콜을 하면, 실질적으론 운영체제의 코드가 돌고 있을 때
- 위 상황은 커널 모드에서 러닝하고 있다 != 운영체제가 러닝하고 있다
- 인터럽트 들어오면 사용자 프로그램이 실행되다 운영체제 커널의 코드가 실행되는데,
- 이는 interrupt service routine 이 실행되는 거고,
- 외부의 요인에 의해 인터럽트가 들어오는 거지만 그래도 user mode 가 계속 돌아가고 있다고 간주함
- 단지 커널 모드(모니터 모드)에서 러닝하고 있다고 부를 뿐
- 사용자 프로그램의 상태도를 의미하지, 운영체제의 상태도를 말하는 게 아님!
Suspended
- Blocked 에서 suspended 되었는지 / ready 에서 되었는지에 따라 차이가 있음
- 외부적인 이유로 프로세스가 완전 얼어붙으면 inactive
- 외부에서 프로세스를 정지시켜 다시 외부에서 재개시켜줘야 active 상태로 돌아갈 수 있음
Suspended blocked
- I/O 같이 오래 걸리는 작업이 끝나면 suspended ready 상태로 바뀔 순 있음
- suspended 는 기본적으로 메모리를 아예 잃어버리는 swap out 상황으로, CPU 관점에서는 아무 일을 할 수는 없음
- 근데 I/O 작업 등이 진행 중이었다면 그건 계속 이어갈 수 있기에 suspended ready 상태로 바뀔 수 있다는 의미
# 3-2 Process 2 & 3-3 Process 3
동기식 입출력과 비동기식 입출력
동기식 입출력
- 프로세스 입장에서 먼저 살펴보기
- 프로세스가 입출력 요청하면, 이건 운영체제 통해 해야 함, 본인이 직접 못함
- 프로세스가 운영체제에 입출력 요청하면 이 작업은 오래 걸려서 끝날 때까지 기다려야 함
비동기식 입출력
- 입출력 진행되는 동안 그 프로세스가 곧바로 CPU 잡아 인스트럭션 실행하면 비동기식
동기식 입출력 구현 방법
- 프로세스가 I/O 요청 후, I/O가 완료될 때까지는 일 못함
- 구현 방법 1 = 그동안 CPU 가지고 있는 상태(CPU를 쓰면서 = 낭비하면서)로 기다림
- 구현 방법 2 = 그동안 CPU를 다른 프로세스에 넘겨줌(어차피 I/O 요청한 프로세스가 일 못하니까, 더 효율적으로 일하기 위해 다른 프로세스에 CPU 넘겨줌)
Thread
쓰레드
- CPU를 수행하는 단위
- 쓰레드의 구성 = 각 쓰레드가 독립적으로 가지는 것
- 쓰레드가 동료 쓰레드와 공유
- = 쓰레드들 간에 공유하는 것
- = task
- = 하나의 프로세스 안에 여러 개의 프로세스가 있고, task 는 한 개로 이루어진 구조
- Lightweight 프로세스 라고도 부름
- 프로세스보다 쓰레드를 여러 개 두는 게 훨씬 가볍기에
- 프로세스 내부의 CPU 수행 단위가 여러 개 있는 것
- 코드 데이터 stack 으로 구성된 주소공간이 프로세스마다 만들어짐
- 프로세스 하나를 관리하기 위해 운영체제 내부에 PCB라는 걸 둠으로써 프로세스 상태나 아이디를 나타냄
- 프로세스가 여러 개 있고, 그걸 별도의 프로세스로 만들면 프로세스마다 별도의 주소공간이 만들어져 메모리 낭비됨
- 같은 일을 하는 프로세스 여러 개 띄워두고 싶으면 메모리 공간은 하나만 띄우고, 각 프로세스마다 다른 코드를 실행할 수 있게 해주는 게 쓰레드의 개념
- 프로세스는 하나만 띄워두고 현재 CPU가 코드의 어느 부분을 실행 중인지, 즉 프로그램 카운터만 여러 개 둔다,
- 즉, 프로세스 하나에 CPU 수행 단위만 여러 개 두고 있는 것을 쓰레드라 부름
프로그램 카운터
- 메모리의 어느 부분을 실행 중인지 가리키는 레지스터
- 프로세스 하나 주어지면 그 프로세스만의 코드, 데이터, 스택이 만들어지고
- PCB에서 현재 메모리의 어느 부분을 실행 중인지 프로그램 카운터가 가리키고 있음
- CPU 수행 위해(= 인스트럭션 실행 위해), 코드의 어느 부분을 실행하는지 가리키는 프로그램 카운터 있어야
- CPU 에서 실행되면서 메모리의 어떤 레지스터 값을 실행하고 있을 거임
- 각 CPU 수행 단위마다(= 각 쓰레다마다), 현재 레지스터에 어떤 값을 넣고 프로그램 카운터가 어느 부분을 가리키며 실행하고 있는지를 별도로 유지
쓰레드들 간에 공유하는 정보
- 프로세스 하나에서 공유할 수 있는 건 최대한 공유
- 메모리 주소 공간 공유
- 프로세스 상태도 공유
- 프로세스가 사용하는 각종 자원도 공유
쓰레드들 간에 별도로 가지고 있는 정보
- CPU 수행과 관련된 정보
- 프로그램 카운터
- 레지스터
- 스택 등
- 쓰레드 하나가 코드 어느 부분을 실행하다 함수 호출 및 리턴하면 그 정보를 스택에 쌓아야
- CPU 수행 단위가 여러 개면 스택도 별도로 둬야
장점1) 하나의 쓰레드가 blocked 일 때 다른 하나는 running = 응답 시간을 빠르게 해줌
- 네트워크 통해 웹페이지 읽어올 때의 작업도 I/O 작업
- 웹페이지를 읽어오는 시간은 오래 걸리니, 내 웹브라우저는 blocked 상태가 됨
- 사용자 입장에서는 웹페이지를 다 읽어오기까지 화면에 아무 것도 나타나지 않기에 답답함
- 웹브라우저를 여러 개의 쓰레드를 사용해 구성하면 또다른 쓰레드가 이미 읽어온 텍스트라도 화면에 디스플레이해줄 수 있음 = 결과를 보다 빨리 볼 수 있음
장점2) 하나의 프로세스 내에 여러 쓰레드를 두면 자원 절약 효과
- 같은 일을 하는 작업을 별도의 프로세스로 만들게 되면 각각의 메모리에 프로세스가 올라가기에 메모리 등 자원이 낭비됨
- 프로세스 하나가 만들어지면 프로세스만의 독자적 주소 공간이 만들어지는데, 이는 메모리를 차지함
- 각각의 코드 데이터 스택을 메모리에 가지고 올라가기에 메모리 낭비 심함
장점3) CPU가 여러 개 달린 컴퓨터에서 얻을 수 있는 장점 = 병렬성
- 행과 열을 곱하는 게 독립적 연산인데, CPU가 하나면 순차적으로 실행해야 하지만, 서로 다른 CPU에서 연산 실행 후 합쳐주면 더 빠른 결과가 나올 수 있음
- 여러 개의 쓰레드 사용 시 각 쓰레드들이 서로 다른 CPU에서 실행되고, 그럼 parallel 하게(병렬적으로) 실행되며, 더 빠른 결과 낼 수 있음
PCB
- 프로세스마다 하나의 PCB가 만들어지는데, 운영체제가 이를 관리함
- 프로세스가 하나면 PCB는 하나만 만들어짐
- 근데 이 프로세스 안에 쓰레드가 여러 개면 CPU 수행과 관련된 정보만 각각 쓰레드마다 별도의 카피를 가지게 됨 = 프로그램 카운터, 레지스터 정보 등
- 쓰레드는 프로세스마다 가지고 있는 정보 중 CPU 관련 정보만 각 쓰레드마다 별도로 가지게 됨
프로세스
- 메모리 주소 공간에 코드, 데이터, 스택이 있고
- 각 프로세스마다 PCB 있고
- 이때 쓰레드는 프로세스 안에서 독자적으로 가져야 할 정보만 별도로 가짐 = PCB의 프로그램 카운터, 레지스터
- 주소 공간에서는 코드와 데이터는 공유하고, 스택 부분만 쓰레드마다 별도로 가짐
Single and Multi-threaded Processes
Single threaded
- 쓰레드 하나
- 코드, 데이터 등의 자원은 쓰레드들이 공유
Multi-threaded
- 쓰레드 여럿
- 레지스터 set, 스택 등은 쓰레드마다 별도로 가짐
- 그림 속 바이너리는 일단 무시하기
Benefits of Threads
빠른 응답성
- 내가 웹브라우저 띄우고, 포털 사이트 홈페이지 주소를 치면 제일 먼저 그 홈페이지에서 HTML 문서 날아옴
- 그 HTML을 웹브라우저 화면에 디스플레이하려 하니 그 문서 안에는 여러 임베디드된 이미지가 있음
- 그것들을 웹브라우저가 해석해서 이미지를 웹서버에게 다시 요청
- 그 이미지들이 다 도착하면 HTML 화면에 텍스트, 이미지 등 넣어 문서 완성 후 사용자에게 보여줌
- 이 과정에서 HTML 문서 읽은 후 그 안의 이미지는 다시 웹서버에 요청 = 오래 걸리는 작업이기에 blocked 시키면 사용자는 답답함
- 그래서 이걸 여러 쓰레드로 만들면
- HTML 문서 가져와서 그 안의 이미지 파일을 웹서버에 다시 요청하는 순간 원래 그 프로세스는 blocked 되는데
- 여러 쓰레드에서 그 요청을 한 쓰레드만 blocked 되고
- 다른 쓰레드가 이미 읽어온 HTML 문서라도 화면에 디스플레이해주면 사용자 입장에서는 답답함이 덜함
- 이미지 파일을 읽는 동안 = I/O 실행시키는 동안, 이 프로그램을 blocked 시키지 않고 텍스트라도 먼저 가져와 보여줌
- 이미지 가져오는 작업과 텍스트 가져오는 작업이 개별적으로 진행됨
- = 비동기식 작업
- = 쓰레드 이용한 응답성 향상
자원 공유
- 하나의 프로세스에서 CPU 수행 단위만 여러 개 두면 코드/데이터/각종 자원은 쓰레드들이 공유하며 자원을 효율적으로 쓰는 효과 얻음
경제성
- 프로세스를 하나 만든다 = 오버헤드 상당히 큼
- 프로세스 내에 쓰레드 추가한다
- = 오버헤드 그다지 크지 않음
- = 쓰레드 간 CPU 스위치가 일어나는 건 간단함
- = 동일한 주소 공간을 쓰고 있기에 대부분 문맥을 그대로 사용
- 컨텍스트 스위치
- = 하나의 프로세스에서 또다른 프로세스로 CPU가 넘어감
- = 오버헤드 상당히 큼
- = CPU 관련 정보 저장, 캐시 메모리 플러시 등
- 같은 일 하는 작업 만들 땐 가능하면 여러 개의 쓰레드를 만드는 게 효율적
Multi-processor 아키텍처
- 프로세스는 하나지만 그 안에 여러 개의 쓰레드를 두면, 각각의 쓰레드가 서로 다른 CPU에서 병렬적으로 일할 수 있음
- 굉장히 큰 행열을 곱한다던지
Implementation of Threads
커널 쓰레드
- 쓰레드가 여러 개 있다는 사실을 운영체제 커널이 알고 있음
- 하나의 쓰레드에서 다른 쓰레드로 CPU가 넘어가는 것도 커널이 CPU 스케줄링하듯 넘겨주게 됨
유저 쓰레드
- 라이브러리 통해 지원됨
- 프로세스 안에 쓰레드가 여러 개 있다는 걸 운영체제는 모름
- 유저 프로그램이 라이브러리의 지원을 받아, 스스로 여러 개의 쓰레드를 관리
- 어떻게 보면 커널이 모르고 있고, 커널이 볼 땐 일반적인 프로세스 같지만, 프로세스 본인이 내부에서 CPU 수행 단위를 여러 개 두면서 관리하기에, 약간의 구현 상의 제약점이 있을 수는 있음
'CS' 카테고리의 다른 글
운영체제 - 반효경 #5 CPU Scheduling & Process Synchronization (0) | 2023.04.10 |
---|---|
운영체제 - 반효경 #4 Process Management (0) | 2023.03.17 |
운영체제 - 반효경 #2 System Structure & Program Execution (0) | 2023.02.16 |
운영체제 - 반효경 #1 Introduction to Operating Systems (0) | 2023.02.08 |
[CS] About IDE (0) | 2022.03.02 |
댓글