개발을 할수록 기초가 중요하다는 생각을 많이 하게 됩니다.
앞으로는 개발에만 치중하기 보다는 틈틈이 배경 지식도 복습하면서 정리해보려고 합니다.
프로그램
실행 가능하지만 아직 실행중이 아닌 디스크에 저장된 코드와 자원의 뭉치입니다. 실행 파일 그 자체. (executable file)
프로세스
프로그램이 실행중인 상태입니다. 실행중이란, 메모리에 올라가고(loaded) 활성 상태를 가지며 이에 따라 정해진 명령을 수행하는 것을 의미합니다.
PC에 chrome을 설치해서 저장된 상태라면 chrome은 프로그램이고, 이걸 실행시켰다면 chrome 프로그램은 자원을 할당 받고 프로세스가 됩니다. 그 때부터 실행중인 chrome은 process id를 부여 받고 실행되며, 작업 관리자나 활성 상태 보기 등을 통해서 이를 확인할 수 있습니다.
(공룡책에서는 program은 passive entity이고 process는 active entity 임을 강조하고 있습니다.)
프로그램이 이제 메모리에 올라갔습니다. 프로세스는 메모리에서 크게 Text, Data, Heap, Stack 네가지 섹션으로 구분됩니다.
(UNIX 시스템 기준으로 상위 1GB는 커널이, 하위 3GB는 사용자 애플리케이션이 차지합니다.)
text(=code): 컴파일된 기계어 binary 소스 코드
data: 전역 변수(global variables)와 정적 변수(static variables), 프로세스를 실행할 때 할당되고 종료할 때 소멸.
크게는 Data영역, 세분화하면 BSS와 GVAR(data) 영역으로 나뉩니다.
-> BSS: 초기화되지 않은 변수로, runtime에 0으로 초기화시킨다.
-> GVAR(data): 초기화된 변수
why?
1. BSS영역은 runtime에 0으로 초기화합니다. 즉, 초기화 데이터를 미리 저장해놓을 필요가 없기에 실행 파일의 크기에 영향을 주지 않습니다.
GVAR영역은 메모리에 로드될 때 초기화된 값을 메모리에 복사하며, 이는 실행 파일에 포함됩니다.
2. 로딩 효율성면에서도, BSS영역은 단순히 메모리를 0으로 초기화할 수 있어서 속도와 메모리 할당에 유리합니다. 반면, GVAR영역은 실행 파일에서 읽어서 메모리에 복사하므로 약간 더 많은 시간이 소요됩니다.
stack: 임시 데이터(지역 변수, 매개 변수, 리턴 값)가 저장되는 영역입니다. 메모리의 높은 주소에서 낮은 주소 방향으로 할당이 되며, stack 자료 구조 방식(push & pop)으로 함수 호출과 함께 할당되며, 함수 리턴 시에 소멸합니다.
heap: 런타임에 동적으로 할당되는 영역입니다. malloc, new 같은 연산자로 필요에 따라 할당하고 free, delete 또는 gc에 의해서 해제되는(해야하는) 데이터들이 여기에 해당합니다.
그림에서 알 수 있듯이 stack과 heap은 같은 영역을 공유합니다. stack은 위에서 아래 방향으로 heap은 아래에서 위 방향으로 공간을 차지합니다. stack 영역은 os에 따라 고정된 메모리 크기를 갖습니다.
무한 재귀 또는 정해진 stack 사이즈보다 큰 지역 변수를 선언하는 경우에 stack overflow 에러가 발생하고, 동적으로 메모리를 계속 할당하여 stack 영역을 침범하거나 이미 해제된 메모리를 포인터로 접근하는 경우에 heap overflow가 발생합니다.
따라서 내가 대용량 데이터를 다룬다거나 오래동안 돌아가는 애플리케이션을 개발중이라면 반드시 메모리 관리를 신경써야 합니다!
프로세스는 메모리에서 프로세스 고유의 공간을 가집니다. 같은 프로그램을 실행하여 두개의 프로세스가 생겼다고 할지라도 이 둘은 별개의 프로세스입니다.
예를 들면, chrome은 멀티프로세스 구조를 가진 애플리케이션입니다.
- browser: UI와 I/O 담당
- renderer: 웹 페이지 렌더링
- plug-in: 플러그인 실행
각각의 역할을 가지며 경우에 따라 자식 프로세스를 만듭니다. 우리가 보는 브라우저 탭이 그것인데,탭을 추가하면 child process(renderer)가 spawn 됩니다.
이렇게 생성된 프로세스 역시 고유 id를 가진 개별적인 프로세스이며 이런 구조 덕분에 하나의 탭에서 오류가 발생해도 브라우저 전체가 다운되지 않을 수 있게 됩니다.
애플리케이션 설계시에 고려해볼 좋은 포인트가 될 것 같습니다.
OS는 PCB(process control block, 또는 task control block)라는 자료 구조에 각각의 프로세스정보를 담아 관리합니다.
PCB에는 아래 그림과 같은 정보들을 포함합니다.
Program Counter와 CPU Registers는 프로세스가 제대로 동작하기 위해 interrupt이 발생할 때 반드시 저장되어야 하는 값입니다.
그 외에 Process State와 CPU 스케줄링 정보, 메모리 관리 정보, I/O 상태 정보 등이 포함됩니다.

PCB의 Process State는 현재 프로세스의 상태를 나타냅니다.

하나의 프로세서에서는 하나의 프로세스가 실행됩니다. 따라서 싱글프로세서 환경에서는 한 프로세스만 running이고 대부분은 ready 또는 waiting 상태로 기다립니다.
지금까지 프로세스에 대해서 간략히 정리해보았습니다. 교과서에서는 Process와 Job이라는 말을 혼용해서 사용합니다. 경우에 따라 뉘앙스가 좀 다르긴 하지만 같은 의미로 봐도 무관할 것 같습니다.
컴퓨터는 우리의 일을 대신 해줍니다. 해야할 일의 로직을 정해주면 일꾼(Processor)는 그 일(Job)을 합니다. 우리는 이에 그치지 않고 컴퓨터가 빠르게 동시에 여러가지 일을 해주길 원합니다.
이건 동시성(Concurrency)에 대한 이야기입니다. 다음은 동시성에 대해 정리해보겠습니다.