프로세스
•
프로세스는 운영 체제에서 실행 중인 프로그램을 나타내는 단위로, 연속적으로 실행되고 있는 컴퓨터 프로그램을 말한다. 프로세스는 실행 중인 프로그램의 인스턴스로, 컴퓨터 시스템에서 작업을 수행하는 주체이다.
•
프로그램은 일반적으로 하드 디스크에 저장되어 있는 실행 코드를 의미하고, 프로세스는 프로그램을 구동하여 프로그램의 상태가 메모리 상에서 실행되는 작업을 지칭한다.
•
프로그램이 실행될 때, 운영 체제는 해당 프로그램을 위한 프로세스를 생성하여 메모리에 로드하고 실행한다. 프로세스는 운영 체제에서 프로그램 코드와 함께 데이터, 스택, 힙 등의 메모리 영역을 할당받아 실행되며, 프로그램이 종료되면 할당된 자원을 반환하고 프로세스가 종료된다.
•
프로세스가 생성되면 프로세스 제어 블록(PCB, Process Control Block)이라 불리는 자료구조에 프로세스의 정보들을 저장한다.
•
여러 개의 프로세스를 사용하는 것을 멀티 프로세싱이라고 하며, 같은 시간에 여러 개의 프로그램을 동작 시키는 시분할 방식을 멀티태스킹이라고 한다.
프로세스의 특징
•
독립성
각각의 프로세스는 독립적인 실행 흐름을 가지며, 하나의 프로세스가 오류로 인해 중단되더라도 다른 프로세스는 계속 실행될 수 있다.
•
자원 할당
프로세스는 운영 체제로부터 CPU 시간, 메모리, 파일, 네트워크 연결 등 필요한 자원을 할당받아 사용하고, 운영체제에 의해 자원을 요청하거나 반환할 수 있도록 관리된다.
•
스케줄링 단위
운영 체제에서 스케줄링의 기본 단위로 작업(task)를 사용하는데 작업의 기준이 프로세스이다. 여러 프로세스가 동시에 실행되는 경우, 스케줄링 알고리즘을 통해 프로세스들을 조율하여 CPU를 공평하게 할당한다.
•
프로세스 간 통신
프로세스는 운영 체제에서 제공하는 메커니즘으로 다른 프로세스와 통신하여 데이터 공유나 메세지 전달 등의 작업을 수행할 수 있다.
프로세스의 메모리 구조
•
모든 프로세스는 아래 그림과 같은 구조를 갖는다. 아래와 같은 주소 공간을 가상 메모리 혹은 논리적 메모리(logical memory)라고 부른다.
•
코드(Code) 영역
코드 영역은 프로그램의 실행 코드나 작성한 프로그램 코드가 저장되는 영역으로, 주로 실행 가능한 명령어들이 포함되어 있다. 일반적으로 읽기 전용(Read-Only) 상태로 설정되어 있고, 프로세스가 실행될 때 코드 영역을 메모리 상으로 로드하여 CPU에 의해 실행된다.
•
데이터(Data) 영역
데이터 영역은 전역 변수, 정적 변수, 상수 등의 데이터가 저장되는 영역으로, 초기화 된 데이터가 저장되는 영역과 초기화 되지 않은 데이터가 저장되는 영역(BSS)로 나누어진다. 초기화 된 데이터는 프로그램 실행 전 초기값이 할당되며, 초기화 되지 않은 데이터는 프로그램 실행 시 0으로 초기화 된다.
•
힙(Heap) 영역
힙 영역은 동적으로 할당되는 메모리 영역으로, 프로그램에서 동적으로 메모리를 할당하고 해제하는 경우에 사용된다. 주로 프로그램 실행 중 변수나 객체, 배열 등을 동적으로 할당하게되면 힙 영역에 메모리를 할당하여 사용한다. 힙 영역은 프로세스의 크기와 스택 영역의 크기에 따라 확장되거나 축소 될 수 있다.
•
스택(Stack) 영역
스택 영역은 함수 호출 시의 매개 변수나 지역 변수, 복귀 주소가 저장되는 영역으로, 함수 호출이 종료되면 해당 스택 프레임이 제거된다. 스택은 후입선출(LIFO, Last-In-First-Out) 방식으로 동작하며, 프로세스의 크기가 정적으로 할당되기 때문에 재귀함수를 반복하여 호출하거나 지역 변수를 너무 많이 선언하게 되면 stack overflow가 발생한다.
부모-자식 프로세스 관계
•
프로세스는 부모 프로세스에서 자식 프로세스를 생성하여 만들어낸다. 이렇게 생성된 프로세스들은 각자의 고유한 pid를 가지고 있다.
•
일반적으로 운영체제에서는 프로세스들을 위 그림처럼 init 프로세스를 root로 하는 트리 구조로 관리한다.
init 프로세스
Linux, UNIX 계열의 OS에서 최초로 실행되는 데몬 프로세스이며 항상 PID 1 값을 가진다.
프로세스의 생성과 소멸
•
일반적으로 프로세스를 생성하는 과정의 시작은 부모 프로세스에서 fork()와 같은 시스템 콜을 호출하여 자식 프로세스를 생성한다.
•
fork()와 같은 시스템 콜을 통해 자식 프로세스가 생성될 때 부모 프로세스에서 PCB(Process Control Block)가 자식 프로세스에 복사된다. 이를 통해 자식 프로세스가 독립적으로 실행될 수 있는 정보를 저장한다.
•
자식 프로세스에 메모리의 새로운 가상 주소 공간을 할당하여 코드, 데이터, 힙, 스택 등의 세그먼트로 나누고, 부모 프로세스의 주소 공간에서 각 세그먼트를 메모리 페이지 단위로 복사한다. 이렇게 부모 프로세스의 메모리 공간을 그대로 복사해서 자식 프로세스에게 할당하는 과정을 주소 공간 복사라 부른다.
•
주소 공간 복사가 끝나면 자식 프로세스의 페이지 테이블을 설정하여, 가상 주소와 실제 물리적인 메모리 주소를 매핑한다.
•
자식 프로세스가 독립적으로 실행되기 위해서, exec()와 같은 시스템 콜을 통해 할당 받은 메모리 공간을 새로운 프로그램을 로드하고 그 프로그램에 대한 작업 수행을 시작한다.
•
이후 프로세스가 작업을 완료거나 exit()과 같이 프로세스를 종료하는 시스템 콜을 호출하면 해당 프로세스는 소멸하게 된다. 먄약 부모 프로세스가 자식 프로세스보다 먼저 종료되면, 자식 프로세스는 작업을 수행 중이더라도 강제로 종료된다.