초기의 컴퓨터 시스템은 한 번에 하나의 프로그램만 실행할 수 있었다. 이는 한 번에 하나의 프로그램만 메모리에 적재하고, 그 프로그램을 실행한 후 종료되면 다음 프로그램을 적재하고 실행하는 방식을 사용했다는 뜻이다.
반면, 현대의 컴퓨터 시스템은 여러 프로그램을 메모리에 적재하고 동시에(병렬적) 실행할 수 있다. 이로 인해 다양한 프로그램을 제어하고 메모리를 효율적으로 분할할 필요성이 증가하였고, 프로세스라는 개념이 도입되었다.
프로그램 (Program)
프로그램(Program)은 컴퓨터에서 실행할 수 있는 명령어들의 집합으로, 기억 장치에 저장되어 파일 시스템에 존재하는 실행 파일이다. 프로그램은 명령어들의 집합일 뿐 그 자체만으로는 아무것도 할 수 없는 수동적인 존재(Passive Entity)이다.
[프로그램의 메모리 구조]
| Text(Code) Section | 실행 코드가 저장되는 영역으로 코드 영역이라고도 부르며, 프로그램에서 정의한 모든 함수의 기계어를 담고 있다. |
|
| Data Section | .data Section | 초기 값을 가진 모든 전역 변수 및 정적 변수가 저장되는 영역 |
| .BSS Section | 초기화되지 않은 모든 전역 변수 및 정적 변수가 저장되는 영역 | |
| .rodata Section | 읽기 전용(Constant) 전역 변수가 저장되는 영역 | |
- .rodata Section
부동소수타입 상수(const float PI = 3.141592f), const 키워드로 정의된 전역 인스턴스(const MyClass gMyclass) 등이 해당된다. 정수타입 상수의 경우 매니페스트 상수(Manifest constant) 처럼 취급되어 사용되는 기계어 코드 위치에 직접 삽입되기 때문에 .rodata Section에 저장되지 않는다.
프로세스 (Process)
프로세스(Process)는 실행 중인 프로그램을 의미한다. 이는 프로그램이 메모리에 적재되고, 운영체제의 제어를 받아 CPU에 의해 실행되고 있는 상태를 의미한다.
[프로세스의 실행을 위한 자원]
운영체제에서 프로세스는 작업의 단위로, 각 프로세스는 독립적인 시스템 자원을 할당받아 실행된다. 이러한 자원에는 다음이 포함된다.
| CPU Time | 프로세스는 CPU를 사용하여 명령어를 실행하기 위해 필요한 처리 시간을 할당 |
| Memory | 각 프로세스는 코드, 데이터, 스택 세그먼트를 포함한 고유한 메모리 공간을 할당 운영체제는 주소 공간을 분리하여 프로세스 간의 메모리 보호와 독립성을 보장 |
| I/O device | 파일 시스템, 네트워크 인터페이스 등과 같은 다양한 입출력 장치에 대한 접근 필요 |
| PCB (Process Control Block) | 운영체제가 각 프로세스를 관리하기 위해 사용하는 데이터 구조체 |
| Network | 프로세스가 네트워크를 통해 데이터를 송수신할 때 사용하는 자원 |
| Synchronization & Communication | 여러 프로세스가 동시에 실행될 때, 자원의 경쟁 조건을 방지하고 데이터의 일관성을 유지하기 위해 동기화 메커니즘 |
[프로세스의 메모리 구조]
프로그램을 실행하도록 운영체제에 요청하면, 운영체제는 프로그램을 메모리에 적재한다. 이는 프로세스가 자신만의 독립적인 메모리 영역, 즉 주소 공간을 갖게 됨을 의미한다. 이 메모리 영역은 보통 Text, Data, Heap, Stack 으로 구분된다.

| Text(Code) Section | 실행 코드가 저장되는 영역으로 코드 영역이라고도 부르며, 프로그램에서 정의한 모든 함수의 기계어를 담고 있다. |
|
| Data Section | .data Section | 초기 값을 가진 모든 전역 변수 및 정적 변수가 저장되는 영역 |
| .BSS Section | 초기화되지 않은 모든 전역 변수 및 정적 변수가 저장되는 영역 | |
| .rodata Section | 읽기 전용(Constant) 전역 변수가 저장되는 영역 | |
| Stack Section | 함수 호출과 관련된 임시 데이터가 저장되는 영역으로, 함수의 매개변수, 복귀 주소, 지역 변수 등이 저장된다. |
|
| Heap Section | 프로그램 실행 중 동적으로 할당된 데이터가 저장되는 영역으로, 사용자가 직접 관리해야 하는 메모리 영역이다. |
|
프로그램이 실행되는 동안 텍스트와 데이터 영역의 크기는 고정되지만, 스택과 힙 영역은 동적으로 변한다. 스택은 높은 주소에서 낮은 주소, 힙은 낮은 주소에서 높은 주소로 확장된다. 만약 프로그램이 스택과 힙이 계속해서 확장된다면, 결국 두 영역이 충돌하거나 겹치는 상황이 발생할 수 있다. 때문에 운영체제는 이를 방지하기 위한 조치를 취한다.
- 스택 영역 : 스택 영역은 메모리의 높은 주소에서 낮은 주소 방향으로 커진다. 함수가 호출될 때마다 활성화 레코드(Activation Record)가 스택에 푸시(Push)되어 크기가 커지며, 함수가 종료될 때 팝(Pop)되어 크기가 작아진다.
- 힙 영역 : 힙 영역은 메모리의 낮은 주소에서 높은 주소 방향으로 커진다. 메모리가 동적으로 할당됨에 따라 크기가 커지고, 메모리가 시스템에 반환되면 작아진다.
프로세스의 상태
프로세스가 생성되어 실행을 마치고 종료될 때까지, 프로세스는 여러 가지 상태를 거치며 변화하고, 각 상태에 따라 동작한다.
| 생성 (New) | 프로세스를 위한 각종 자료구조는 생성되었지만 아직 메모리 획득을 승인받지 못한 상태 |
| 준비 (Ready) | CPU를 할당을 기다리는 상태 상태. 프로세스가 CPU만 보유하면 명령을 실행할 수 있지만, 아직 할당받지 못한 상태 |
| 실행 (Running) | CPU를 할당 받아 기계어 명령을 실행하고 있는 상태 |
| 대기 (Waiting) | CPU를 할당 받아도 명령을 실행할 수 없는 상태 입출력 요청 또는 시간이 오래 걸리는 작업을 진행하기 위해 대기하는 상태 |
| 종료 (Terminated) | 프로세스는 종료되었으나 관련 자료구조가 완전히 정리하지 못한 상태 |
[프로세스의 상태 전이]
프로세스가 가질 수 있는 상태 중에서 대기 상태를 제외한 다른 상태들은 운영체제에 의해 제어된다. 운영체제는 프로세스의 상태를 감시하고, 현재 프로세스의 상태를 기반으로 프로세스 스케쥴링을 통해 프로세스를 관리하고 제어한다.

| ① Admitted (New → Ready) | - |
| ② Exit (Runngin → Terminated) | - |
| ③ Interrupt (Running → Ready) | 프로세스 실행 중 인터럽트가 발생하여 CPU 제어권을 이전하고 준비 상태로 전환 |
| ④ Dispatch (Ready → Running) | 프로세스 스케줄러가 준비 상태에 있는 프로세스 중 실행할 프로세스를 선택하고, CPU를 해당 프로세스에게 할당하여 실행 상태로 전환 |
| ⑤ Wake Up (Wait → Ready) | CPU를 사용하지 않고 긴 대기 시간이 필요한 작업(입출력 이벤트, 자원 할당 대기 등)으로 인해 대기 상태로 전환된 프로세스가 해당 작업이 완료되어 다시 준비 상태로 전환 |
| ⑥ Block (Running → Wait) | CPU를 사용하지 않고 긴 대기 시간이 필요한 작업(입출력 이벤트, 자원 할당 대기 등)이 발생하여 CPU 제어권을 반환하고 대기 상태로 전환 |
프로세스간 자원 공유
내용 추가 예정
'OS' 카테고리의 다른 글
| [OS] 프로세스 스케줄링(Process Scheduling) (0) | 2024.07.29 |
|---|---|
| [OS] 메모리 관리 (0) | 2024.01.13 |
| [OS] 5. 상호배제 (Mutual Exclusion) - 작성중 (0) | 2024.01.13 |
| [OS] 3. 프로세스 (Process) (0) | 2024.01.13 |
| [OS] 컴퓨터 시스템의 동작 (0) | 2024.01.13 |