Kernel , User 영역에서 Process에 관해서 말해보고자 한다.
우선 프로세스란 쉽게 말해서 실행 중인 프로그램이라고 생각하면 된다.
같은 Process인 메모장이 별개의 Process로 관리되는 것을 볼 수 있다.
Process는 크게 2가지로 나눌 수 있는데
- 프로그라운드 프로세스
사용자와 직접 상호작용 하고 있는 프로세스 - BackGround Process
사용자와 직접 상호작용 하고 있지 않은 프로세스
다만 이중에선 Daemon, Service와 같이 특별한 프로세스도 있다. => 맡은 바 묵묵히 실행만 되는 프로세스
각각의 Process 마다 PCB (프로세스 제어 블록) 이 있는데 , 일종의 프로세스의 꼬리표 같은 느낌.
운영체제는 PCB를 보고 Process를 판단한다. 위 예시에서 각각의 메모장 ( 별도의 프로세스)는 각각 PCB를 가지고 있는 것이다. 이는 Kernel 영역의 메모리에 적재되어있다.
어떤 Process를 새롭게 실행했다면, PCB가 생성되고 프로세스를 종료한다면 PCB는 삭제된다.
PCB는 다양한 정보들을 포함하고 있는데
1. PID (Process ID)
2. 레지스터 관련 정보 & 스케줄링 정보
3. 메모리 정보
이 프로세스가 메모리 어디에 적재되어 있는지 알아야하니까
4. 사용한 파일 정보 & 입출력 장치 정보
Linux Kernel에서는 task_struct라는 PCB 구조체가 있다. => 훨씬 더 Deep 하니 알아보면 좋다.
CPU가 수 많은 Process를 관리해야하는데, cpu 자원의 수가 부족하다 ?
=> Context Switching (문맥 교환) => 정해진 시간으로 Process 를 번갈아 보면서 관리한다.
Process A 실행 -> B 실행 -> A 실행 -> B 실행 이렇게 반복을 해야하는데 그럼 CPU ( 레지스터, 제어장치, 카운터) 등에 적혀있는 정보 또한 교체를 해주어야한다. 이 과정을 Context Switching
그리고 프로세스 A가 끝나는 시점에는, 내가 어디까지 했다는 내용을 적어놔야하는데 => Stack에 Backup을 해두게 된다.
Context Switching이 빠르면 빠를 수록, 동시에 실행되는 것 처럼 느껴질 것이다. But Context Switching도 비용이 있기 때문에 너무 자주 발생하면 성능이 저하될 수도 있다.
그렇다면 Kernel 영역에서는 PCB로 관리하고 그럼, User 영역에서는 ??
1. 코드 영역
실행 가능한 코드, 기계어로 이루어진 명령어. => Read Only 영역으로 지정된 경우가 많음.
2. 데이터 영역
프로그램이 실행되는 동안 유지할 데이터
3. Heap 영역
사용자(개발자)가 직접 할당 가능한 공간. , 메모리 영역을 할당했으면은 꼭 해제하자 ! -> memory leak 위험
혹은 자동으로 해제할 수도 있음 ( 가비지 컬렉션)
낮은 주소에서 높은 주소로 할당된다.
4. Stack 영역
임시로 저장되는 영역 ( 매개 변수, 지역 변수)
Stack 영역은 높은 주소에서 낮은 주소로 할당 ( 주소 중복을 방지)
코드 영역과 데이터 영역은 사이즈가 바뀌지 않는다. => 정적 영역
Heap, Stack은 얼마든지 바뀔 수 있다 => 동적 영역
size 명령어로 hello 실행파일의 text 영역의 size, data영역의 size 들을 확인할 수 있다.
대표적인 Process의 상태에는 5가지가 있다.
생성 상태(new) => | 이제 막 PCB를 항당받아서 생성된 상태 |
준비 상태(ready) => W | 지금 당장이라도 자원을 받아서 실행될 수 있지만, 아직 내 차례가 오지않아서 실행되지 않은 상태 |
실행 상태(running) => R | 자원을 할당 받아서 실행이 되고 있는 상태 |
대기 상태(blocked) => Sleeping | 대기 하고 있는 상태, 주로 입출력장치 사용을 요청했을 때 대기 상태가 된다. 지금 당장 실행될수는 없는 상태 특정한 이벤트가 발생해야 하고, 이벤트를 기다리고 있는 상태 |
종료 상태(terminated) => S | 프로세스 실행이 끝나고, PCB가 폐기되고 자원을 반납하고 있는 상태 |
Dispatch => CPU로 부터 자원을 할당받는 과정을 말한다.
실행 상태에서 입출력 요청을 받는다면, 대기상태로 접어들었다가
원하는 입출력 event가 발생하면 다시 준비 상태로 들어가게 된다.
top 명령어로 S 부분을 보면 Process의 상태를 확인 할 수 있다.
여기서 Z가 나오면은 Zombie process인데
프로세스 종료 후에 자원은 반환되었지만, Kernel 영역에 프로세스가 남아있는 상태를 말한다.
프로세스는 대부분 아래 사진처럼 계층적인 구조를 가진다
계층적인 Process 구조는 pstree 명령어로 확인해 볼 수 있다. 이렇게 계층 구조를 이룰 수 있는 원리는 fork exec인데
fork system call을 호출하면, 자신과 동일한 Process가 자식 Process로 생성되게 된다.
별개의 process 이므로 주소도 다르고 ,PID 또한 다르다.
fork() 로 부모 Process 를 복제한 뒤에는 exec() 명령어를 통해서 새로운 코드를 실행할 수 있다.
fork -> 복사 느낌이고, exec -> 옷 갈아입는 느낌
재밌당
'컴퓨터 공학 > 운영체제' 카테고리의 다른 글
프로세스와 스레드(2) (0) | 2023.12.19 |
---|