chapter 03. 프로세스
프로세스란?
⇒ a program in execution. 실행중인 프로그램을 말한다!
운영체제 입장에서 프로세스란, 작업의 단위!(the unit of work)
프로세스가 실행되기 위해서는 특정 자원들이 필요하다.
•
CPU time - cpu를 줄 수 있어야하고,
•
memory - 메모리에 올라가(로딩 되어) 있어야 하고,
•
files
•
I/O devices - 파일이나 입출력 장치 등의 resource들을 관리 할 수 있어야 한다.
지난 챕터에서 공부했던, 폰노이만 아키텍처 구조의 컴퓨터는 위의 그림처럼 메모리에 로딩된 명령어를 cpu가 fetch해서 execute하는 구조이다.
•
(강아지 한테 공 던져주면서 “물어와!” 하는 것도 “fetch it!”이라고 한다..)
우리가 ./a.out 등의 명령어를 통해 HDD, SSD등의 하드웨어 storage에 저장되어있는 a.out 파일을 실행 하거나 GUI 환경에서 더블 클릭등을 하면, 해당 프로그램을 실행하기 위해 우선 메모리에 a.out을 로드하게 되는데, cpu가 fetch할 수 있게 메모리에 로드 된 이 상태에 있는 프로그램을 “프로세스” 라고 한다.
메모리에 로드되었다고 해서 다 실행되는 건 아니다. 이 프로세스가 cpu를 점유 해야하는데, 여러개의 프로세스가 time sharing을 통해 동시에 cpu를 공유하고 있다. cpu를 점유했다면 이 프로세스는 실행 될것이고, 실행되면서 다른 file들이나 입출력 device들을 관리 할 수 있다.
OS가 가장 기본적으로 해야하는 일 : 프로세스를 관리하는 일이다!
여러 섹션으로 나누어져 있는 어떤 프로세스의 메모리 layout
•
Text section : 실행할 명령어들로 이루어진 부분(실행 가능한 code)
•
Data section : 전역변수들
•
Heap section : 동적할당된 메모리들
•
Stack section : 호출된 함수 스택들
어떤 프로그램이 시작하는 메모리 영역이 0번지 이고(logical한 0번지! 실제 0번지가 아님) 이 프로그램의 최대 메모리 영역이 max라고 하면, 제일 먼저 text section에 code(실행 코드들)를 올리고, data 영역에 전역변수들을 올리고, stack 영역은 max 영역부터 내려오면서 함수 호출이 쌓이고, 이 메모리 영역이 부족해 지면 extra 메모리를 또 할당해 오면서 쓰면 됨.
왼쪽의 소스코드를 컴파일 하면 프로그램이 되고, 이 프로그램이 이렇게 메모리에 로드되면 프로세스(실행중인 프로그램)가 됨. ⇒ OS는 “프로세스”를 관리한다!
프로세스의 생명주기(state, life cycle)
•
New : 프로세스가 막 생성된 상태
•
Running : 프로세스가 cpu를 점유해서, cpu가 프로세스를 실행하는 상태
•
Waiting : cpu는 time sharing을 통해 여러 프로세스가 공유하므로, 다른 프로세스가 cpu를 점유해서 쓰고 있을 때 cpu를 공유하고 있는 다른 프로세스들은 waiting 상태가 된다. 보통 어떤 작업을 오래해서 cpu를 오래 작업한 경우, 혹은 I/O 작업이 끝날때 까지(I/O가 끝났다는 시그널을 받을 때 까지) 기다리는 경우가 있다.
•
Ready : I/O작업이 다 끝났다고 시그널을 받았다고 해서 바로 cpu를 점유 할 수 있는 건 아니다. 레디 큐에서 “이제 cpu를 점유할 준비가 다 되었으니, 곧 점유하겠다!”하는 상태
•
Terminated : 프로세스의 일을 마친 상태
◦
fork() 시스템 콜을 통해 “새로운 프로세스를 하나 만들어줘”라고 OS에 서비스 요청.
◦
⇒new 상태
◦
초기화 및 승인이 끝난 이후, cpu를 획득하기 위해 ready 상태가 됨.(ready queue에 들어가 있는 상태)
◦
cpu scheduling을 통해, 운영체제가 해당 프로세스에게 cpu를 주면 ⇒ running 상태
(scheduler가 dispatch 해서 cpu를 준다.)
◦
running 상태에서 일을 하고 있다가 스스로 cpu를 너무 오래 쓴다고 감지하거나 혹은 운영체제가 cpu를 너무 오래 쓴다고 interrupt를 주면 ⇒다시 ready로 가서 대기
◦
혹은 running 도중 I/O나 event wait가 있을 때 자발적으로 waiting 상태가 됨.⇒waiting queue에서 대기
◦
⇒ I/O 및 이벤트가 끝나면 ⇒ ready 상태로 되돌아감.
◦
running 도중, exit 및 return을 하면, terminated상태가 된다.
◦
⇒ 운영체제가 프로세스로부터 메모리, 자원 등등을 다 회수한다.
프로세스를 어떻게 관리할 것인가?
PCB → 가장 좋은 방법
process control block 이라는 구조체(or 클래스)를 하나 만든다.
⇒ 이 구조체에 프로세스가 가져야 하는 모든 정보를 다 저장한다.
•
TCB ( Task Control Block)이라고 하기도 한다.
PCB가 가지고 있는 정보
•
프로세스의 상태 : new / running / waiting/ ready / terminated
•
program counter(PC) : 레지스터 중의 하나
◦
다음에 실행된 명령어를 가지고 있다. ⇒ 명령어 포인터 라고도 한다.⇒ 인텔 계열에서는 IP(Instruction Pointer)라고도 한다.
•
CPU registers : cpu 안에 있는 레지스터들의 정보(IR, DR등등)
—> 프로그램 카운터나 CPU 레지스터를 문맥(context)라고 한다! ⇒ 뒤에서 더 다룰 내용!
•
CPU-scheduling information : cpu를 주거나 release 하기 위해서 필요한 정보들
•
Memory-management information : 메모리 할당 정보들(메모리를 얼마나 크기로 했고 등등)
•
Accounting information : 계정정보. 어떤 유저가 creation 했는지 등등
•
I/O status information : 어떤 파일을 오픈 했고, 어떤 자원을 오픈했고 또 lock을 걸어 놨는지 등등
각 프로세스 마다 PCB들이 있으므로, 운영체제가 PCBs를 관리 해주어야한다.
“A process is a program that performs a single thread of execution”
프로세스는 기본적으로 single thread of execution을 한다!
시분할을 통해 a single thread of execution은 쭉 이어지면서 실행된다.
이 single thread of execution은 한번에 오로지 한 task만 할 수 있기때문에,
여러개를 동시에 실행하려면 multiple threads of execution을 해야한다.
⇒ 이를 통해 multitasking 과 multiprocessing이 가능해진다.( 멀티 태스킹과 멀티프로세싱을 할 필요가 없다면, 사실상 운영체제라는 복잡한 프로그램의 필요성이 없어짐. 운영체제의 매우 핵심적인 기능)
또, 프로그램이 복잡해지면서, 프로세스 안에서도 싱글 쓰레드로는 부족해지기 시작. 프로그램 내에서도 하나의 쓰레드가 동시에 실행될 필요가 있어졌다.
Thread!(a sigle thread of execution에서 따온 새로운 개념!)
•
프로세스보다 더 가벼운 프로세스!( a lightweight process)
•
프로세스를 여러개 하는 것 보다 쓰레드를 여러개 하는게 더 장점이 많다!
•
요새는 멀티 프로세스 보다는 멀티 쓰레딩이 대세!
멀티프로그래밍의 목적! ⇒ 여러개의 프로세스를 동시에 사용해보자!
at the same time = simultaneouly = concurrently
≠ parallel! ⇒ 다름!
타임쉐어링의 목적 ⇒ CPU를 점유하는 프로세스들간에 전환을 아주 빠르게 해서, 사용자 입장에서는 동시에 running 되는 것 처럼 보이기 위함.
스케줄링 큐(FIFO) : ready 큐에 있다가 running상태가 되는데(cpu를 점유), 때에따라 waiting 큐로 가기도 함.
밑의 4개가 waiting 큐.
일반적인 프로세스 스케쥴링의 형태
Context Switch(문맥 교환)
⇒ 문맥? : 프로세스가 사용되고 있는 상태를 문맥이라고 한다. ⇒ 이 상태는 PCB에 저장되어 있음. 운영체제 입장에선 PCB라고 이해하면 된다.
어떤 interrupt가 일어 났을 때, running하고 있는 프로세스의 현재 문맥(PC)을 저장하고, 다시 CPU를 획득했을 저장해 놓은 문맥으로 복원(restore)한다.
문맥 교환⇒CPU 를 다른 프로세스에게 넘겨주는것
•
현재 프로세스의 문맥을 저장하고
•
새로 cpu를 획득할 문맥으로 복원한다.
process creation
⇒ 하나의 프로세스가 여러개(대여섯개)의 새로운 프로세스를 생성할 수 있다.
a tree of process
init 프로세스가 자식 프로세스를 생성.
•
부모 프로세스도 계속 실행되고, 자식 프로세스도 concurrently 하게 계속 실행하는 방식
•
부모 프로세스가 자식 프로세스가 terminated 될때까지 wait 하는항식
pid : process id
3-9 그림 중요!
fork()를 통해 process를 생성하고, return , exit을 통해 프로세스를 terminate 한다.
Zombid and Orphan
Zombie 프로세스 : 부모 프로세스는 있지만 신경을 안 쓰는 프로세스 → wait()를 호출하지 않고 부모 프로세스가 자신의 일만 계속 하는 경우
Orphan 프로세스 : 부모 프로세스 없는 프로세스→ 부모 프로세스가 wait()을 호출하지 않고 종료된 경우.