프로세스
운영체제는 프로세스 형태로 동작하는 다양한 프로그램을 실행합니다.
- 프로세스 = 실행중인 프로그램 = active entity
- 프로그램 = 디스크 상에 있는 코드들의 집합 = passive entity
프로세스는 무조건!! 순차적으로 실행됩니다. 싱글 프로세스에서 명령어들은 병렬적으로 실행되지 않습니다. 하나의 statement는 오직 하나의 CPU 에서만 실행됩니다.
그리고, 하나의 프로그램이 여러 개의 프로세스를 생성할 수 있습니다. 다수의 유저가 하나의 프로그램을 실행시킬 경우, 해당 프로그램은 다수의 프로세스를 생성합니다.
구성요소
- text (= code) : 프로그램 코드
- program counter : 어디까지 실행했는지
- register : 레지스터의 상태
- stack : temporary data (파라미터, 리턴 주소, 지역변수 등)
- data : 전역변수
- heap : run-time에서 동적으로 할당되는 메모리 영역
Process in Memory
Stack
- 지역변수, 매개변수, 리턴 주소
- 함수 호출과 함께 할당되고, 함수 호출이 완료되면 소멸
- run-time에 크기 결정
Heap
- 동적 할당, 객체, 배열 등
- run-time에 크기 결정
Data
- 전역변수, 정적변수
- 프로세스 시작과 함께 할당, 종료와 함께 소멸
Text
Java를 예로 들면
문자열의 경우, 문자열 값은 힙에 저장되고 스택에는 힙의 주소가 저장됩니다. 그러니까 일종의 포인터입니다.
Process State
5개의 상태가 있습니다.
- New : 생성
- Running : 실행 중
- Waiting : 이벤트 발생 시 까지 대기 (ex. scanf)
- Ready : 준비완료
- Terminated : 실행 종료
Process Control Block (PCB)
OS의 프로세스 관리 단위입니다. 다음과 같은 값들이 저장됩니다.
- Process state
- Program counter
- CPU registers
- CPU scheduling information
- Memory-management information
- Accounting information : CPU 사용량, 실행 시간, time limit
- I/O status information : 할당된 디바이스, 열린 파일들 리스트 등
리눅스에서는 double-linked-list를 사용해서 관리합니다.
이렇게 연결리스트를 활용하여 프로세스를 전환합니다.
Process Scheduling
ready 상태의 프로세스들 중에서 다음에 CPU 코어에서 실행될 프로세스를 선택하는 과정입니다. CPU 사용량을 최대로 하는 것이 목표입니다. scheduling queues를 이용하여 관리합니다.
- Ready queue : 실행 대기 중 및 준비 완료 상태
- Wait queue : I/O 와 같은 이벤트를 기다리는 프로세스들
이런 느낌으로, 모든 프로세스는 종료될 때까지 이런 과정을 반복합니다. 프로세스 종료 시, 위에 모든 큐에서 제거되고 해당 프로세스의 PCB와 자원들(메모리)가 해제됩니다.
context-switch
프로세스를 전환할 때 발생됩니다. 아래 그림처럼 PCB를 저장하고 로드하는 과정에서 CPU는 대기 상태를 가집니다. context-switch가 많이 발생할 때 overhead가 크다고 하고 이는 성능 저하를 초래합니다.
- library-call : 프로세스 안에서 실행됩니다. 따라서 해당 프로세스를 계속 실행합니다.
- system-call : 실행 중 커널을 실행했다가 다시 프로세스를 실행합니다. 이 때, context-switch가 발생합니다.