사전적 의미의 프로그램이란 '어떤 작업을 위해 실행 할 수 있는 파일'을 말한다.
1) 사용자가 프로그램의 실행을 요청하면
2) 보조 기억장치에 저장되어 있는 프로그램의 정보를 읽어 메모리에 이를 로드한다.
3) CPU는 메모리에 로드된 프로그램 코드를 가져와 메모리를 관리하고 명령어들을 실행하는데
4) 동적 메모리가 할당되면 FreeStore 영역을 위에서 아래로 할당하며 사용하고
5) 지역변수, 매개변수 등의 스택 메모리가 할당되면 Free Store 영역을 아래에서 위로 할당하며 사용한다.
사전적 의미의 프로세스란 컴퓨터에서 연속적으로 실행되고 있는 프로그램을 말한다.
하지만 컴퓨터가 아닌 사람의 입장에서 가장 명확히 이해할만한 프로세스의 정의란
메모리에 올라와 실행되고 있는 프로그램의 인스턴스
라고 할 수 있겠다. 즉, 운영체제로 부터 시스템 자원을 할당받는 작업의 단위가 바로 '프로세스' 이고, 동적인 개념으로는 실행되고 있는 프로그램을 의미 한다.
그렇다면 운영체제로 부터 할당 받는 시스템 자원이란 어떤 것이 있을까?
각 프로세스들을 그림으로 구조화 해보면 다음과 같이 나타낼 수 있겠다.
4개의 메모리 영역 Code, Heap, Stack, Data 영역이 구성되어 있는 구조를 살펴보자.
메모리 주소가 낮은 곳에서부터 Code 영역, Data 영역이 위치하고 FreeStore 영역에 Heap 영역, Stack 영역이 자리하게 된다.
이 때, 사용자가 동적으로 할당하는 메모리들을 Heap 영역에, 주소가 낮은 곳에서 높은 곳으로 자리하고 함수 내에서 사용되는 지역변수나 매개변수들은 Stack 영역에, 메모리 주소가 높은 곳에서 낮은 곳으로 자리하게 된다.
왜 이렇게 나눠진 것일까?
공유할 수 있는 데이터를 최대한 공유해 메모리를 효율적으로 사용하기 위해!
- Code 영역 = 같은 프로그램 자체에서는 모두 같은 내용이기 때문에 따로 관리하여 공유
- Stack과 Data를 나눈 이유는, 스택 구조의 특성과 전역 변수의 활용성을 위한 것!
- 가장 나중에 호출된 func3() 이 가장 먼저 나오게 됨!
- func1, func2, func3 에서 공통으로 사용하는 데이터는 전역 변수로 선언해 사용 메모리를 줄일 수 있음
FreeStore 영역 내에서 Heap 영역과 Stack 영역에 로드되는 데이터들이 많아지다 보면 두 영역이 서로 침범하는 경우가 발생하는데, 이를 오버플로우라 한다.
그림에서도 나타나듯이 두 영역의 주소 할당 방향은 마주보는 형태이다.
그렇다면 스레드란 무엇일까?
스레드의 사전적 의미는 '프로세스 내에서 실행되는 여러 흐름의 단위'이다.
보다 와닿는 의미로는 다음과 같이 이해하면 좋을 듯 하다.
프로세스가 할당받은 자원을 이용하는 실행의 단위
프로세스 내 스레드의 자원 이용 형태는 사진과 같다.
💡 스레드에 Stack만 따로 할당하는 이유는 무엇일까?
: 각 스레드는 각각의 실행 시퀀스 / 코드를 가질 수 있으므로 함수가 호출되고 반환될 때 각각의 PC (Program counter)를 push / pop 해야 함
즉, 스레드 사이의 보호를 위해 Stack을 구분
💡 Program Counter
- CPU 레지스터 종류 중 하나
- 다음에 실행할 명령어의 주소를 저장함
- 스레드에 독립적으로 할당된 PC -> 여러 스레드가 수행될 때 각 스레드의 PC는 명령어의 어디까지 수행되었는지를 저장함!
- 그런데 레지스터는 프로세서가 가지고 있지 않은가?
실제로는 스레드가 갖고 있는 레지스터는 저장된 상태 를 의미한다고 생각하면 조금 더 명확할 것 같다.
멀티 스레드 환경에서 Context Switching 이 발생하는데 프로세스 내에서 여러 스레드 사이의 Context Switching 은 Code/Data/Heap 영역을 공유하고 있기 때문에, 결국 실행중이던 스레드가 어디까지 실행되었는지와, Stack 영역의 상태만 메모리에 저장하고 다른 스레드로 주도권을 넘겨주게 된다.
멀티 프로세스 환경에서도 마찬가지로, 실행중이던 프로세스를 중단하고 다른 프로세스로 점유가 넘어갈 때 실행중이던 프로세스에 대한 정보를 담는 공간이 필요하다.
이 두경우의 정보가 담기는 공간이 TCB, PCB 이다.
보통 TCB는 커널 레벨에서 Context Switching의 기본 단위가 되며, 같은 프로세스에서의 스위칭에 대해서는 TCB 정보만 저장하면 된다.
하지만 다른 프로세스 간의 스위칭을 할 때에는 PCB / TCB 정보를 모두 저장해야 한다.
All-young's Blog
OS Context Switching에서의 Thread와 Process의 관계 + PCB, TCB
쓰레드에 레지스터가 있다?