[운영체제] 프로세스의 이해
서론
이 강의는 유튜브 - 주니온TV의 운영체제 강의를 듣고 정리한 내용을 기록한 게시물입니다.
프로세스란?
프로세스는 Program in Execution, 실행되고 있는 프로그램을 말한다.
하나의 프로세스가 실행하기 위해서는 다음과 같은 자원이 필요하다.
- CPU Time
- Memory
- File, I/O devices 등의 Resource
따라서 메모리에 올라 올 수 있고, CPU를 점유할 수 있으며 파일과 입출력 디바이스에 접근할 수 있는 것이 프로세스이다.
이 프로세스를 관리하는 것이 운영체제의 가장 중요한 내용중에 하나이다.
프로세스의 구조
Text Section
실행 가능한 코드의 영역
Data Section
전역 변수의 영역
Heap Section
C++ 의 경우 malloc(), Java의 경우 new 키워드를 통해 확보한 메모리가 존재하는 영역
Stack Section
호출한 함수가 쌓이는 영역으로, 함수 파라미터, 리턴 주소, 지역변수가 존재하는 영역
이것을 그림으로 보면, text영역이 가장 아래 주소에 할당되고, stack 영역이 가장 위의 주소부터 할당된 영역을 갖게된다. (여기서 주소는 물리적 주소가 아닌 논리적 주소)
프로세스의 생명 주기
New
프로세스가 생성된 상태
Running
CPU를 점유해서 프로세스의 명령어를 실행하고 있는 상태
Waiting
다른 프로세스가 CPU를 점유했을때, CPU를 점유하지 못하고 대기하는 상태
Ready
CPU를 점유하기 전 상태로, 준비를 마치고 레디큐에 들어가있는 상태
Terminated
프로세스가 종료된 상태
Process Control Block
운영체제는 이러한 프로세스의 정보를 기록하기 위해 PCB를 사용한다.
PCB에는 다음과 같은 정보가 저장된다.
- 프로세스의 상태
- Program Counter
- CPU Registers
- CPU 스케줄링 정보
- 계정 정보
- 입출력 상태 정보
PCB는 위 그림과 같이 하나의 구조체로 이루어져있다.
프로세스 스케줄링
따라서 운영체제는 프로세스를 바꿔가면서 마치 여러개의 프로그램이 동시에 돌아가는 것 처럼 보이도록한다. 이를 위해서는 시간을 쪼개 여러 프로세스가 CPU를 점유할 수 있도록 이를 스케줄링 해주어야 한다.
위 그림은 프로세스 스케줄링의 과정을 다이어그램으로 표현한 그림이다.
그림을 보면 레디큐에 있는 프로세스가 순차적으로 CPU를 점유하는 것을 볼 수 있는데, CPU 점유가 끝나고 프로세스의 Running 상태가 해제되는 이유는 아래와 같이 4가지가 있다.
I/O Request
입력이나 출력 요청이 있을경우, 해당요청을 처리할 동안 다른 프로세스가 CPU를 점유하게 된다.
Time Slice Expired
CPU는 하나의 프로세스가 너무 오래 CPU를 점유하는 것을 막기위해, 각 프로세스의 시간을 정해놓는다. 따라서 할당된 시간이 지나면 해당 프로세스는 READY 상태로 바뀌고 다른 프로세스가 CPU를 점유한다.
fork a child
프로세스가 fork()를 통해서 생성된 새로운 자식 프로세스가 레디큐에 들어가게 된다.
wait for an interrupt
인터럽트를 기다리고 있다면, 인터럽트 발생 후 레디 큐에 들어가게 된다.
Context Switching
현재 CPU를 점유하고 있는 프로세스가 현재까지의 작업을 저장하고, 다른 프로세스가 CPU를 점유하는 작업을 Context Switching이라고한다.
여기서 Context (문맥)은 바로 PCB를 가르키는데, 현재 프로세스의 상태를 PCB에 저장하고, CPU를 새로 점유하게 될 프로세스의 PCB를 불러와 해당 정보를 읽어오는 행위가 마치 현재 작성하던 문맥의 글을 다른 것으로 바꾸는 것과 비슷하다고 하여 문맥교환, Context Switching 이라고 한다.
CPU는 무수히 많은 컨텍스트 스위칭을 통해 여러 프로세스의 현재까지의 작업을 저장하고, 이전에 진행했던 작업의 정보를 불러와 중단시켰던 작업을 마저 이어서 진행 할 수 있다.
fork() 와 exec()
프로세스를 임의로 생성하고자 할때는 fork 함수를 사용하면 된다. fork 함수를 호출하는 프로세스는 부모 프로세스가 되고, 새롭게 생성되는 프로세스는 자식 프로세스가 된다.
fork()를 호출하게 되면, fort()를 호출한 프로세스를 새로운 공간으로 전부 복사하게 되고, 원래 프로세스는 원래 프로세스대로 작업을 실행하며, fork()를 통해 생성된 프로세스도 fork() 시스템 콜의 다음 라인부터 실행하게 된다.
반면에 exec()은 새로운 프로세스를 위한 메모리를 할당하지 않고 호출한뒤, 기존의 프로세스가 사용하던 메모리와 관리 체계를 그대로 사용하고 기존코드를 지우고 자신의 새로운 코드를 덮어 쓰게 된다.
따라서 fork()는 새로운 프로세스(PID가 완전히 다른 프로세스)가 생성되며, exec()은 기존 프로세스와 PID가 같은 프로세스위에 새로운 프로세스를 덮어쓰게 된다.
댓글남기기