공룡책 요약하기 03
Process
오늘날의 컴퓨터 시스템들은 메모리에 다수의 프로그램들이 적재되어 병행 실행되는 것을 허용한다.
이를 위해 다양한 프로그램을 보다 견고하게 제어하고 보다 구획화하는 것이 요구된다.
프로세스란 실행 중인 프로그램을 말하며, 현대 시분할 시스템에서 작업의 단위이다.
프로그램이 수동적인 존재인 것과 대조적으로 프로세스는 다음에 실행할 명령어를 지정하는 프로그램 카운터와 관련 자원의 집합을 가진 능동적인 존재(active entity)이다.
프로세스는 일반적으로 함수의 매개변수, 복귀 주소와 로컬 변수와 같은 임시적 자료를 가지는 프로세스 스택과 전역 변수들을 수록하는 데이터 섹션, 프로세스 실행 중에 동적으로 할당되는 메모리인 힙을 포함한다.
프로세스는 실행되면서 그 상태가 변한다.
- 새로운(new): 프로세스가 생성 중이다.
- 실행(running): 명령어들이 실행되고 있다.
- 대기(waiting): 프로세스가 어떤 사건이 일어나기를 기다린다.
- 준비 완료(ready): 프로세스가 처리기에 할당되기를 기다린다.
- 종료(terminated): 프로세스의 실행이 종료되었다.
어느 한 순간에 한 처리기상에서는 오직 하나의 프로세스만이 실행된다.
그렇지만 많은 프로세스가 준비 완료 및 대기 상태에 있을 수 있다.
각 프로세스는 운영체제에서 프로세스 제어 블록(PCB)에 의해 표현된다.
PCB는 특정 프로세스와 연관된 여러 정보를 수록하며, 다음과 같은 것들을 포함한다.
- 프로세스 상태
- CPU 스케줄링 정보
- 메모리 관리 정보: 기준(base) 레지스터와 한계(limit) 레지스터의 값, 페이지 테이블, 세그먼트 테이블 등
- 회계 정보: CPU 사용 시간과 경과된 시간, 시간 제한, 계정 번호, 잡 또는 프로세스 번호 등
-
입출력 상태 정보: 프로세스 할당된 입출력 장치들과 열린 파일의 목록 등
- 프로그램 카운터: 프로세스가 다음에 실행할 명령어의 주소
- CPU 레지스터: 누산기, 인덱스 레지스터, 스택 레지스터, 범용 레지스터, 상태 코드 정보
프로그램 카운터와 상태 정보는 나중에 프로세스가 계속 올바르게 실행되도록 하기 위해서, 인터럽트 발생 시 저장되어야 한다.
다중 프로그래밍의 목적은 항상 어떤 프로세스가 실행되도록 하는 데 있다.
시분할의 목적은 사용자가 상호 작용할 수 있도록 프로세스들 사이에서 CPU를 빈번하게 교체하는 것이다.
이 목적을 달성하기 위해 프로세스 스케줄러는 CPU에서 실행 가능한 여러 프로세스를 선택한다.
단일 처리기 시스템에서는 실행 중인 프로세스가 한 개 이상 있을 수 없다.
만일 프로세스들이 여러 개가 있다면, 나머지 프로세스들은 CPU가 자유로워 다시 스케줄 될 때까지 대기해야만 한다.
프로세스가 시스템에 들어오면, 이들은 잡 큐에 놓여진다.
주 메모리에 존재하며 준비 완료 상태에서 실행을 대기하는 프로세스들은 준비 완료 큐라 불리는 리스트 상에 유지된다.
이 큐의 헤더는 리스트의 첫번째와 마지막 PCB를 가리키는 포인터를 포함한다.
각 PCB는 준비 완료 큐에 있는 다음 프로세스를 가리키는 포인터 필드를 가진다.
새로운 프로세스는 처음에 준비 완료 큐에 놓인다.
프로세스는 CPU에 할당(dispatch)받을 때까지 준비 완료 큐에서 대기한다.
일단 프로세스에 CPU가 할당되어 실행되면,
-
프로세스가 입출력 요청을 하여 입출력 큐에 넣어진다.
-
프로세스가 새로운 자식 프로세스를 생성하고 자식 프로세스의 종료를 기다릴 수 있다.
-
인터럽트의 결과로 의해 강제로 CPU로부터 제거되고 준비 완료 큐에 다시 놓인다.
중의 하나가 발생할 수 있다.
처음의 두 경우에서, 프로세스는 대기 상태에서 준비 완료 상태로 전환되고ㅡ 다시 준비 완료 큐에 넣어진다.
프로세스는 종료될 때까지 이 주기를 계속하며, 종료되면 모든 큐에서 삭제되고 그 자신의 PCB와 자원을 반납(deallocate)한다.
즉시 실행될 수 있는 것보다 더 많은 프로세스들이 제출되면 대용량 메모리(디스크)에 저장되어 나중에 실행될 때까지 유지된다.
장기 스케줄러는 이 풀에서 프로세스들을 선택하여 실행하기 위해 메모리로 적재한다.
단기 스케줄러는 실행 준비가 완료되어 있는 프로세스들 중에 선택하여 이들 중 하나에게 CPU를 할당한다.
어떤 시스템에서는 장기 스케줄러가 없거나 기능이 적다.
UNIX나 WINDOWS같은 시분할 시스템들은 장기 스케줄러가 없으며 모든 새로운 프로세스를 단기 스케줄러를 위하여 단순히 메모리에 넣는다.
대신 중기 스케줄러를 도입하여 메모리에서 프로세스를 제거함으로써 다중 프로그램의 정도를 조절한다.
차후에 다시 프로세스를 메모리로 불러와서 중단되었던 지점에서부터 실행을 재개한다.
이러한 기법을 스와핑이라고 한다.
CPU를 다른 프로세스로 교환하려면 이전의 프로세스의 상태를 보관하고 새로운 프로세스의 보관된 상태를 복구하는 작업이 필요하다.
이 작업은 문맥 교환(context switch)이라고 한다.
문맥 교환이 일어나면 커널은 과거 프로세스의 문맥을 PCB에 저장하고 새로운 프로세스의 저장된 문맥을 복구한다.
운영체제 내에 실행되는 프로세들은 독립적이거나 협력적인 프로세스들일 수 있다.
프로세스 협력 환경을 제공하는 이유는 정보 공유,계산 가속화,모듈성과 편의성이 있다.
- 정보 공유
- 여러 사용자가 동일한 정보에 흥미를 가질 수 있으므로, 그러한 정보를 병행적으로 접근할 수 있는 환경을 제공해야 한다.
- 계산 가속화
- 특정 태스크를 빨리 실행하고자 한다면 그것을 서브태스크로 나누어 이들이 각각 다른 서브태스크들과 병렬 실행되게 해야 한다. 이러한 가속화는 복수 개의 처리 코어를 가진 경우에만 달성할 수 있다.
- 모듈성
- 시스템 기능을 프로세스들 또는 스레드들로 나누어 모듈식 형태로 시스템을 구성한다.
- 편의성
- 개별 사용자들이 한 순간에 작업할 많은 태스크를 가질 수도 있다. 예를 들면 한 사용자가 편집, 음악 듣기 및 컴파일 작업 등을 병렬로 할 수 있다.
협력적 프로세스들은 프로세스간 통신 기법(IPC)을 필요로 한다.
프로세스간 통신에는 공유 메모리와 메세지 전달의 두 가지 모델이 있다.
- 공유 메모리
- 컴퓨터 환경에서 여러 프로그램이 동시에 접근할 수 있는 메모리이다. 과다한 복사를 피하거나 해당 프로그램 간 통신을 위해 고안되었다. 공유 메모리 영역을 구축할 때만 시스템 호출이 필요하므로 메세지 전달보다 더 빠르다. 공유 메모리 영역이 구축되면 모든 접근은 일반적인 메모리 접근으로 취급되어 커널의 도움이 필요 없다.
- 메시지 전달
- 협력 프로세스들 사이에 교환되는 메시지를 통하여 통신이 이루어진다. 메시지 전달 모델은 충돌을 회피할 필요가 없기 때문에 적은 양의 데이터를 교환하는 데 유용하다. 또한 분산 시스템에서 공유메모리 보다 구현하기 쉽다.
많은 처리 코어를 가진 시스템 상에서의 연구에 따르면 메시지 전달이 공유 메모리보다 더 나은 성능을 보이는데, 공유 메모리는 공유 데이터가 여러 캐시 사이에서 이주하기 때문에 캐시 일관성 문제로 인하여 성능 저하가 발생하기 때문이다.