Os 3 Process
프로세스의 개념
Process is program in execution
프로세스란 실행 중인 프로그램을 뜻한다. 일반적으로 잡(Job)과 프로세스를 혼용하기도 한다.
- 실행하면 프로세스 독자적 주소공간(Code, data, stack) 생성
- 프로세스에 CPU 할당되면 프로그램 카운터가 프로세스 주소공간의 하나를 가리킨다
- code에서 Instruction(기계어)를 하나씩 읽어서 CPU 안으로 불러들인다.
- CPU 내부의 레지스터에 값을 넣고 논리연산장치에서 연산한다.
- 결과를 레지스터나 바깥의 메모리에 저장한다.
프로세스의 문맥(Context): 프로그램의 특정 시점
프로세스 문맥(Context)은 인터럽트에 의해 CPU를 빼앗겼다가 다시 획득할 때 정확한 재현을 위해 필요한 정보다.
해당 프로세스의 주소 공간(코드, 데이터, 스택 상태)를 비롯해 레지스터 값, 시스템 콜 등을 통해 커널에서 수행한 일의 상태, 그 프로세스에 관해 커널이 관리한 각종 정보 등을 포함한다.
프로세스 문맥은 크게 하드웨어 문맥, 프로세스의 주소 공간, 커널상의 문맥으로 나뉜다.
- CPU 수행 상태를 나타내는 하드웨어 문맥
- 프로그램 카운터가 어디를 가리키고 있는가(=코드의 어느 부분까지 실행했는가)
- 각종 레지스터
- 프로세스 주소 공간
- 메모리에 어떤 내용을 담고 있는가
- code, data(변수 등), stack
- 프로세스 관련 커널 자료구조
- 프로그램이 실행되면 운영체제는 프로세스를 관리하기 위한 자료구조를 유지
- PCB(Process Control Block)
- 커널 스택: 프로세스를 OS에게 맡길 때 커널스택을 따로 둔다.
프로세스의 상태
프로세스의 상태는 실행(Running), 준비(Ready), 봉쇄(Blocked, wait, sleep)의 세가지로 구분할 수 있다.
실행 상태는 프로세스가 CPU를 보유해 기계어 명령을 실행하고 있는 상태를 가리킨다.
준비 상태는 CPU만 보유하면 당장 명령을 실행할 수 있지만 아직 CPU를 할당받지 못한 상태를 가리킨다.
봉쇄 상태는 CPU를 할당받더라도 당장 명령을 실행할 수 없는 프로세스의 상태를 말한다.
이 밖에 프로세스가 생성 중인 일시적 상태를 시작(New) 상태, 종료 중인 일시적 상태를 완료(Terminated) 상태라고 부르기도 한다.
시작 상태는 프로세스가 시작돼 자료구조는 생성됐지만 메모리 획득을 승인받지 못한 상태다.
완료 상태는 프로세스가 종료됐으나 운영체제가 그 프로세스와 관련된 자료구조를 완전히 정리하지 못한 상태를 말한다.
문맥 교환(Context Switch)는 실행시킬 프로세스를 변경하기 위해 원래 수행 중이던 프로세스 문맥을 저장하고 새로운 프로세스 문맥을 세팅하는 과정이다.
이때 준비 상태에 있는 프로세스들 중에서 CPU를 할당받을 프로세스를 선택한 후 실제 CPU의 제어권을 넘겨받는 과정을 CPU 디스패치(Dispatch)라고 한다.
- 1) Running
- CPU를 잡고 인스트럭션을 수행 중인 상태
- 2) Ready
- 다른 모든 준비 완료, CPU만 오면 되는
- 3) Blocked(wait, sleep)
- CPU를 줘도 당장 인스트럭션 수행 불가능한 상태 예) I/O
- 4) Suspended(stopped)
- 외부적인 이유로 프로세스의 수행이 정지된 상태
- 예를 들어 중기 스케줄러에 의해 생기는 상태로 프로세스는 통째로 디스크에 swap out된다.
- 예) 사용자 프로그램이 일시정지시킨 경우(메모리에 너무 많은 프로세스가 올라와 있을 때)
- 외부적인 이유로 프로세스의 수행이 정지된 상태
- Blcked와 Suspended 구분
- Blocked: 자신이 요청한 이벤트가 만족되면 Ready
- Suspended: 외부에서 재개해주어야 Active
- New: 프로세스 생성 중인 상태
- Terminated: 수행(execution)이 끝난 상태, 약간 정리할 게 남음
- 유의: 프로세스가 시스템콜을 해 운영체제가 제어한다고 운영체제가 운영을하고 있다고 말하지 않는다. 커널 모드에서 러닝한다고 말한다.
프로세스 제어블록
운영체제가 각 프로세스를 관리하기 위해 프로세스당 유지하는 정보(구조체로 유지)
- 1) OS 관리상 사용하는 정보
- Process state, Process ID
- CPU Scheduling information, priority
- 2) CPU 수행 관련 하드웨어 값(문맥)
- 프로그램 카운터, 레지스터
- 3) 메모리 관련(문맥)
- code, data, stack의 위치 정보
- 4) 파일 관련
- Open file descriptors
문맥 교환(Context Switch)
문맥교환은 CPU 제어권이 한 사용자 프로세스에서 다른 사용자 프로세스로 이양되는 과정을 뜻한다.
예를 들어 타이머 인터럽트가 발생하면 CPU 제어권이 사용자 프로세스에서 운영체제로 넘어간다.
그러면 운영체제는 타이머 인터럽트 처리루틴으로 가서 직전까지 수행 중이던 프로세스 문맥을 저장한다. 그리고 실행시킬 프로세스에게 CPU를 이양한다.
이러한 문맥교환 과정에서 CPU를 보유했던 프로세스는 프로그램 카운터값 등의 문맥을 자신의 PCB에 저장한다.
새롭게 CPU를 할당받을 프로세스는 예전에 저장했던 자신의 문맥을 PCB로부터 실제 하드웨어로 복원시키는 과정을 거친다.
문맥교환의 예는 타이머 인터럽트 이외에 입출력 요청 등의 상
- 시스템 콜이나 인터럽트라고 반드시 컨텍스트 스위칭은 아님
- 사용자 프로세스 하나에서 다른 사용자 프로세스로 넘어가는 상황에서 일어나는 것이 컨텍스트 스위칭
- 한 사용자 프로세스 내에서 제어권이 운영체제로 넘어갈 때도 실행위치 등의 문맥을 PCB에 저장하지만 문맥교환이라고 하지는 않는다. 모드만 변한 것이기 때문이다.
- 실제 모드 변경에 비해 문맥교환에는 훨씬 많은 오버헤드가 뒤따른다.
프로세스를 스케줄링하기 위한 큐
운영체제는 준비 상태에 있는 프로세스들을 줄 세우기 위해 준비 큐(ready queue)를 두고 준비 큐의 제일 앞에 줄 서 있는 프로세스에게 먼저 CPU를 할당한다.
준비 큐 이외에 특정 자원을 기다리는 프로세스를 줄 세우기 위한 장치 큐(device queue)도 있다. 이를테면 디스크 입출력을 요청한 프로세스들은 디스크 입출력 큐(disk I/O queue)에 줄 서게 된다.
앞선 하드웨어 자원을 기다리는 프로세스 이외에 소프트웨어 자원을 기다리는 경우에도 큐에 줄을 세운다. 예를 들어 공유 데이터는 일관성을 유지하기 위해 여러 프로세스가 동시에 접근하려고 할 경우 공유 데이터를 기다리는 큐에 줄을 서게 해 현재 공유 데이터를 사용하고 있는 프로세스가 데이터를 반납하기 전까지 접근하지 못하게 한다.
이와 같이 커널은 다양한 큐를 두어 총체적으로 프로세스를 관리한다.
운영체제는 시스템 내 모든 프로세스를 관리하기 위해 작업 큐(job queue)를 둔다. 프로세스의 상태와 무관하게 현재 시스템 내 모든 프로세스가 작업 큐에 속한다. 준비 큐에 속한 프로세스는 준비 상태라면 장치 큐의 프로세스는 봉쇄 상태다. 프로세스는 상태 변화에 따라 준비 큐와 장치 큐를 오가며 실행된다.
큐는 각 프로세스의 PCB를 연결리스트로 관리하며 포인터를 사용해 순서를 정한다.
스케줄러
스케줄러(scheduler)란 어떤 프로세스에게 자원을 할당할지 결정하는 운영체제 커널의 코드를 지칭한다.
장기 스케줄러는 작업 스케줄러(job scheduler)라고도 부르며 어떤 프로세스를 준비 큐에 진입시킬지 결정하는 역할이다. 준비 큐의 프로세스들은 순서가 되면 CPU에서 실행하기 위해 메모리를 보유해야 하므로 장기 스케줄러는 메모리 할당 문제에 관여한다.
한편 단기 스케줄러는 CPU 스케줄러라고도 하며, 준비 상태의 프로세스 중 어떤 프로세스에게 CPU를 할당할지 결정한다. 시분할 시스템에서는 타이머 인터럽트가 발생하며 단기 스케줄러가 호출된다.
그러나 현대 시분할 시스템에서 사용되는 운영체제에서는 장기 스케줄러를 두지 않는 경우가 대부분이다. 과거와 달리 프로세스당 메모리 보유량에 여유가 생겼으므로 프로세스가 시작 상태가 되면 장기 스케줄러 없이 곧장 메모리를 할당해 준비 큐에 넣어준다.
현대 시분할 운영체제에서는 장기 스케줄러 대신 중기 스케줄러를 두는 경우가 많다. 중기 스케줄러는 너무 많은 프로세스가 메모리에 적재돼 프로세스당 보유 메모리양이 적어지면 일부 프로세스 메모리를 통째로 빼앗아 디스크의 스왑 영역에 저장해둔다. 이를 스왑 아웃(Swap out)이라고 한다.
중기 스케줄러가 스왑아웃시키는 0순위 프로세스는 봉쇄 상태의 프로세스들이다. 봉쇄 상태의 프로세스는 당장 CPU를 획덕할 가능성이 없기 때문이다. 그래도 부족하 경우에는 타이머 인터럽트가 발생해 준비 큐로 이동하는 프로세스를 추가적으로 스왑 아웃시킨다.
준비 큐에 많은 프로세스가 존재하면 개발 프로세스에 배정되는 메모리양이 적어지므로 당장 실행시킬 프로세스에 메모리를 추가로 부여하는 게 더 효율적이기 때문이다.
중기 스케줄러의 등장으로 프로세스의 상태에는 실행, 준비, 봉쇄 이외에 중지(suspended, stopped)가 추가된다. 중지 상태의 프로세스는 외부에서 재개시키지 않는 이상 다시 활성화할 수 없으므로 메모리 자원이 당장 필요하지 않다. 따라서 중지 상태의 프로세스는 메모리를 통째로 빼앗기고 스왑 아웃된다.
- 1) Long-term scheduler
- 시작 프로세스 중 어떤 것들을 Ready queue로 보낼지 결정
- degree of multiprogramming(메모리에 올라간 프로세스의 수)을 제어
- Time sharing system에는 보통 장기 스케줄러가 없음(무조건 Ready)
- 지금은 없는 시스템 무조건 Ready로 감. 중기 스케줄러가 현재 시스템
- 2) Short-term scheduler(CPU 스케줄러)
- 어떤 프로세스를 다음번에 러닝시킬지 결정
- 3) Medium-term scheduler(Swapper)
- 여유 공간 마련을 위해 프로세스를 통째로 메모리에서 디스크로 쫓아냄
- 프로세스에게서 메모리를 뺏는 문제
- degree of multiprogramming(메모리에 올라간 프로세스의 수)을 제어
쓰레드
-
쓰레드는 CPU를 수행하는 단위(lightweight process)
- 프로세스 내부에 CPU 수행 단위가 여러 개 있는 것
- 프로세스 주소공간은 하나만 띄워 놓고 코드의 각 다른 부분을 실행
- CPU 수행을 위해 프로그램 카운터, 레지스터 별도로 유지
-
코드를 실행하다가 함수호출하면 정보를 스택에 쌓을텐데 스택도 별도로 유지
-
결국 공유할 수 있는 것들은 공유하고(메모리 주소공간, 프로세스 상태, 프로세스 자원) CPU 수행 관련된 정보는 별도로 가지고 있는다(프로그램 카운터, 레지스터, 스택)
- 쓰레드의 구성
- 프로그램 카운터, 레지스터, 스택
- 쓰레드끼리 공유하는 부분(=Task)
- code, data, os 리소스
쓰레드 사용 장점
- 한 쓰레드가 Blocked 상태일 때 다른 쓰레드가 Running하여 응답속도를 높일 수 있다. 예) 웹 브라우저 네이버 웹페이지 읽어온다(I/O 작업) 아무것도 못하면 답답하니 어려 개 쓰레드로 하면 그림 불러오고 텍스트 불러오고 따로 쓰레드로
- 동일한 일을 수행하는 다중 스레드가 협력해 높은 처리율(throughput) 예) 같은 일 프로세스 여러 개 띄우면 각각 메모리에 올라가야 하기 때문에 메모리 낭비
- 병렬성을 높인다. (CPU가 여러 개일 경우)
- 예) 1000 by 1000 행렬 연산 각 계산을 서로 다른 CPU에서 연산하고 합친다.
- 1) 응답성
- 2) 자원공유
- 3) 경제성
- 4) 멀티프로세서 유틸라이제이션(CPU여러 개일 때만)