프로세스의 정의
프로세스 (process) 란, 실행 중인 프로그램을 뜻한다.
HDD, SSD와 같은 스토리지에 우리가 작성한 코드 파일이 있을 것이다. 이런 명령어들의 집합으로 구성된 프로그램을 실행시키게 되면 해당 정보들이 메모리에 로드 된다. 해당 프로그램은 이제 cpu가 fetch해서 연산할 수 있는 상태가 되는데, 해당 상태에 있는 프로그램을 프로세스 라고 할 수 있겠다. 이제 이 프로세스는 cpu를 점유하거나, 파일을 열거나, I/O 장치들과 신호를 주고 받게 될 것이다. 운영체제가 해야 하는 가장 기본적인 활동은 바로 프로세스를 관리하는 것이다.
프로세스는 위 그림과 같은 주소 공간을 필요로 하게 된다. text 영역에는 우리가 작성한 프로그램 코드가 들어 있고, data에는 전역 변수가, heap 영역에는 동적으로 할당된 메모리가 들어 있다. C에서는 malloc
, Java에서는 new
와 같은 코드가 메모리 동적 할당을 수행한다. stack 영역은 임시 데이터 저장 공간이라고 할 수 있는데 여기는 지역 번수, 함수의 매개 변수, 리턴값의 주소 등이 들어 있다. stack 영역은 위에서부터 아래로 커지고, heap 영역은 아래에서 위로 커지는 방식이다. 이렇게 쭉 쌓아오다가 만약 부족해지면 다른 메모리 영역을 참조하기도 한다.
1 |
|
위 소스 코드가 우리가 일반적으로 작성하는 형태이고, 이를 컴파일 하여 a.out
이라는 프로그램을 만들 수 있다. 해당 프로그램이 메모리에 로드되면서 각각의 section을 차지하게 되는 이런 일련의 동작을 프로세스 라고 할 수 있겠다. (즉, 실행중인 프로그램!)
프로그램을 실행시키는 방법
Load : Disk에 있는 프로그램을 DRAM과 같은 메모리에 프로세스로 적재한다.
Dynamic Allocation : 메모리에 적재된 프로그램의 데이터를 위 그림처럼 배치한다.
Initialization : 미리 처리되어야 할 file descriptor 및 I/O 를 처리한다.
Jump to Entry point : C언어에서는 main() 함수와 같이 시작지점으로 점프한다.
프로세스의 상태
프로세스는 총 다섯 가지 상태를 가질 수 있다.
- new : 프로세스가 생성 되었을 때
- ready : 프로세스가 cpu를 할당 받기를 기다리고 있을 때 (준비 완료!)
- running : 명령어들이 실행되고 있을 때
- waiting : 프로세스가 어떤 이벤트가 발생하기를 기다리고 있을 때
- terminated : 프로세스가 종료 되었을 때
위 그림을 순서대로 해석 해 보자.
fork()
라는 시스템 콜을 통해서 사용자는 프로세스 생성을 os에게 요청할 수 있다. (new 상태)- 프로그램을 프로세스로 만드는 여러 작업들을 거친 후, cpu에게 점유할 준비가 다 되었다고 알려주기 위해 ready queue에 들어간다. (ready 상태)
- cpu 스케쥴러는 이를 확인하고, 정책에 따라 ready 상태의 프로세스를 cpu에 dispatch한다. (running 상태)
- 프로세스는 cpu 스케쥴러의 판단에 따라서 다시 ready 상태로 옮겨지기도 한다. (interrupt 발생)
- 만약 I/O 요청 또는 다른 event가 발생하여 잠시 프로세스의 실행을 멈춰야 할 때도 있다. (waiting 상태)
- I/O 요청이 종료되면, 해당 프로세스는 다시 cpu를 점유할 수 있는 상태가 되므로 ready queue에 들어가서 대기한다.
- 마지막으로
exit()
과 같은 명시적인 종료 시스템 콜이 들어오면, 프로세스는 종료된다. (terminated 상태)
프로세스 컨트롤 블록
프로세스 컨트롤 블록 (Process Control Block, PCB)은 운영체제가 가지고 있는 프로세스에 대한 정보의 총집합이다.
다시 말하면, 운영체제가 프로세스 스케쥴링을 위해 프로세스에 관한 모든 정보를 가지고 있는 데이터베이스를 의미한다.
각 프로세스가 생성될 때 마다 고유의 PCB가 생성되고, 프로세스가 완료되면 제거된다. 이런 정보 구조체가 실제로 어떻게 쓰일까? 프로세스는 기본적으로 cpu를 점유하여 작업을 처리한다. 그런데, 우리가 앞서 살펴본 process state에 따르면 프로세스가 running 상태에 있더라도 특정 이벤트 혹은 interrupt에 의해 ready나 wait 상태로 바뀐다. 이때 PCB를 활용하여, 방금 전까지 작업한 내용들을 전부 저장해 둔다. 이후 다시 해당 프로세스가 cpu를 점유하게 되면 (running 상태) PCB로부터 해당 정보들을 불러와서 작업을 이어서 진행할 수 있게 된다.
PCB는 위 그림과 같은 구조로 이루어져 있다. 중요한 몇 가지만 짚고 넘어가자.
- 프로세스 식별자 (process ID)
- 프로세스 상태 (process state) : ready? wait? 이런 상태들을 저장해두어야 한다.
- 프로그램 카운터 (program counter, pc) : 해당 프로세스가 다음에 실행할 명령어의 주소를 가리킨다.
- cpu 및 일반 레지스터
- cpu 스케쥴링 정보 : 최종 실행 시각, 우선 순위, 점유 시간 등등
- 메모리 관리 정보 : 해당 프로세스의 주소 공간
- 프로세스 계정 정보
- 입출력 상태 정보 : 프로세스에 할당돤 입출력장치 목록, 열린 파일 목록 등
요약
- 프로세스란, 실행 중인 프로그램을 뜻함
- 프로세스가 필요한 메모리 주소 공간은 text, data, heap, stack이 있음
- ready 상태의 프로세스는 cpu 스케쥴러에 의해 running 상태로 바뀜
- running 상태의 프로세스는 I/O interrupt에 의해 wait 상태로 바뀔 수 있음
- running 상태의 프로세스는 cpu 스케쥴러에 의해 interrupt 되어 다시 ready 상태로 바뀔 수 있음
- PCB는 프로세스의 정보를 담고 있는 데이터베이스임. 프로세스가 스케쥴링되어 바뀔 때 유용하게 사용됨
- 특히, 프로그램 카운터 (pc)는 해당 프로세스가 다음에 실행할 명령어의 주소를 저장하고 있음