Process
실행중인 프로그램 또는 실행 단위 또는 현재 상태
하드 디스크의 프로그램 실행 파일을 실행시키면 프로세스가 된다. 프로세스가 되어 필요한 부분들만 메모리 안으로 들어온다. 그래서 프로세스는 하드디스크랑 메인 메모리 사이를 왔다갔다 하면서 작업을 실행하게 된다.
프로세스 구성 정보
- Program code
- A set of Data
- Stack
- 지역 변수들을 저장할 공간
- 함수를 호출했을 때 나중에 어디로 리턴해야 하는지에 대한 리터럴 주소
- PCB(Process Control Block)
- 프로세스가 실행을 하는 과정에 필요한 모든 정보
- OS가 이 프로세스를 관리하기 위해 필요한 정보들을 저장하는 곳
- 프로그램이 실행하다가 중단하는 것을 가능하게 하기 위한 모든 정보
- OS가 만들고 OS가 관리한다.
프로그램이 컴파일 되어서 바이너리 파일 형태로 하드디스크에 있을 때는 프로그램 코드
랑 데이터
만 존재한다. 그 다음 실행을 시작해 프로세스가 되어 메모리로 올라오면 스택 영역
과 PCB
가 추가된다.
Dispatcher

Dispathcer는 OS 코드이다. 어떤 프로그램을 중단하다가 실행하는데, 어떤 프로그램을 실행할지 알 수 없다. OS가 이런 결정을 하고 실행할 수 있게 해주는 작업을 하는게 Dispatcher
이다.
Dispatcher가 작업을 하는 큰 이유
- 타임 쉐어링
- 한 프로그램이 시스템을 전적으로 완전히 사용하지 못하도록 여러 사람이 공동으로 사용하도록 하기 위해

여기서 B는 4개의 명령밖에 실행하지 못했는데 C와 비슷한 크기이다. 이 이유는 I/O 리퀘스트
때문이다. 어떤 프로그램이 실행을 하다가 중단하고 다른 프로그램으로 바뀌는 이유는 2가지이다.
- 타임아웃
- I/O 작업
I/O 작업, 즉 외부에서 입력을 받는 작업은 상당히 시간이 오래 걸리는 작업이다. 따라서 다음 프로그램으로 C를 선택한다.

파란색으로 표현된 부분이 실제로 CPU를 차지하고 실행되는 부분이다. 회색으로 표현된 부분은 CPU를 차지하지 못하고 기다리고 있는 부분이다. 진한 회색 부분은 I/O 작업을 해야해서 I/O 작업이 끝날 때까지 대기하는 상황이다.
- Running : CPU를 차지하고 실행을 하고 있는 상태
- Ready : CPU를 주면 실행할 수 있지만 CPU를 주지 않아서 대기하고 있는 상태
- Blocked : I/O 작업 때문에 대기하고 있는 상태. CPU를 줘도 작업할 수 없다.
DIspathcer는 다음에 실행할 프로세스를 골라야 한다. Ready상태에 있는 프로세스를 골라야 한다. os는 Ready상태의 프로세스와 Blocked 상태의 프로세스를 분리시킨다. 따로 큐에 저장을 해둔다. 그래야 Dispatcher가 다음 프로그램을 고를때 Ready 상태에 있는 프로세스를 고를 수 있다.
큐는 OS가 관리하고 메인 메모리에 저장되어 있다. 큐에는 프로세스 포인터가 들어가있다.
Five-State Model
- New : 실행을 시작하면서부터 프로세스를 만들고 자원을 할당하는 상태. 아직 자원 할당이 끝나지 않았기 때문에 실행을 할 수 없다.
- Ready : 모든 자원이 다 할당되고 메모리 자원까지 할당되면 메모리에 올라온다. Ready 상태인 프로세스들끼리 모여 있는 큐에 존재한다.
- Running : 실행되는 프로세스.
- Blocked : I/O 작업이 끝날 때까지 기다린다. CPU를 줘도 실행할 수 없다.
- Exit : 프로세스한테 할당된 모든 자원들을 반납하고 프로세스를 완전히 시스템에서 제거하는데 시간이 소요된다. 이 작업을 하는동안 프로세스는 Exit 상태에 놓여있다.
Exit 상태에서 모든 상황을 parent process한테 보고를 하는데 당장 보고를 안받을 수도 있다. 그런 경우 프로세스 테이블에 엔트리 하나를 남겨둔다. 왜냐하면 보고를 받아야 되는 프로세스가 그걸 확인하고 확인했다 할 때까지 기다리는 것이다.
그래서 Exit 상태는 마지막으로 보고 받는 프로세스가 확인을 다 하고 해당하는 엔트리가 사라질 때까지 결국 프로세스는 Exit 상태로 죽지 않고 살아있게 된다.
아 그림을 그릴줄 알아야 한다.

Blocked에서 Running 상태로 갈 수 없다. 다시 Ready 상태로 보내고 OS는 Ready 상태에 있는 프로세스 중에서 하나를 골라서 실행시킨다.
Blocked 큐에 저장되는 이유는 여러가지가 있다.
동시에 선택되는 상황을 막기 위해 이벤트별로 별도의 큐를 사용한다.

어떤 이벤트가 발생했을 때 어느 큐에 가서 꺼내와야 하는지 빠르게 할 수 있다.
큐 안에는 프로세스가 들어있는 것이 아니라 프로세스 포인터가 들어가있다.
프로세스는 덩치가 크기 때문에 프로세스를 옮기면 시간이 많이 소요된다. 따라서 프로세스들은 메모리 한 곳에 가만히 존재한다.
OS는 시스템을 관리하는 프로그램이고 관리를 하기 위해서 여라 가지 상황들이 발생하는데 그 상황에서 상식적인 선에서 해결한다.
만약 시스템에 실행하고 싶은 프로그램이 10개인데 10개가 모두 I/O 작업을 하면 더 이상 실행할 프로그램이 없다.
하지만 사실은 백그라운드로 실행되는 프로그램들이 수백 개들이 존재한다. 실제로 시스템 안에는 우리가 실행시키는 프로그램 말고도 굉장히 많은 시스템 프로그램들이 실행되고 있고, 지금 실행하고 싶은 프로그램들은 다 메모리에 집어넣지 못하므로 잘라서 집어넣는다.
그래서 전체 프로그램 중 일부만 메모리에 있고 레디큐가 비어있다라고 한다면, 실행하고 싶은데 메모리에 들어오지 못한 다른 프로세스들이 대기를 하고 있는 상황이다.
Swapping
따라서 OS는 메모리에 들어있는 프로세스를 하드디스크로 버린다. 그리고 실행하고 싶어하는 다른 프로세스를 가지고 온다 = Swapping
하드디스크 : 파일이 저장되는 공간
swapping area : 프로세스가 저장되는 공간
파일 형태로 있다가 실행을 시작하게 되면 프로세스가 된다. 그리고 메인 메모리를 차지하면 메인 메모리 안으로 들어가고, 메모리를 차지하지 못하면 swapping area
에서 기다린다.
그러다가 만약 메모리가 빈다면 메모리에 있던 프로세스를 swapping area
로 보내고 swapping area
에 있는 프로세스를 메모리 안으로 가지고 온다.
하드디스크의 Swapping area
에 있는 프로세스들을 Suspend State
에 있다고 한다.
- New State
- Blocked/Suspend : 블락된 상태에서 스와핑에 의해 하드디스크의
Swapping area
로 쫓겨난 경우
- Ready/Suspend: I/O 작업은 끝났지만 아까 쫓겨나서 여전히 하드디스크에 있는 상태

각각의 상태가 무엇을 의미하는지, 상태가 변할 때 프로세스가 어느 공간에 있는지, 프로세스를 포함하는 시스템 전체 상황을 알아야 한다.
- New → Ready/Suspend
- 메모리가 가득찼는데, 빼낼 프로세스가 없을 때
- Blocked/Suspend → Blocked
- OS가 봤을 때 금방 I/O가 끝날 것 같을 때. swapping을 할 때 그룹으로 옮기는데 프로세스가 속해있는 그룹에 있는 다른 프로세스들이랑 같이 메모리로 올라간다.
- Running → Ready/Suspend
Reasons For Process Suspension
Suspend : 프로세스를 중단시키고 하드디스크로 쫓아낸다. = 아주 오랫동안 실행시키지 않는다.
Swapping
: 메모리 공간은 부족하고 실행하고 싶어하는 프로세스는 많은데 메모리에 와있는 프로세스들이 Blocked 상태라 실행할 수 없을 때, 프로세스를 하드디스크에 보내고 하드디스크에서 실행할 수 있는 프로세스를 다시 메모리로 가져온다.
- I/O속도가 CPU보다 느리기 때문에
- 메모리 공간의 부족
Other OS reason
: 메모리 공간이 넉넉하지 않으면 유틸리티 또는 백그라운드 프로그램들을 먼저 쫓아낸다. 백그라운드 프로그램은 유저와 Interaction이 없다. 시스템은 유저 프로그램을 실행시키는 것이 주 목적이다. 또는 프로그램이 이상한 행동을 하고 있는 것 같다면 하드디스크로 쫓아내고 조사한다.
- 이상한 작업이 의심되어 쫓아낸 경우가
Running
→ Ready/Suspend
이다.
Interactive User Request
: 유저가 실행을 하다가 Suspend를 요청하는 경우에 해당한다. ex) 디버깅
Timing
: 주기적으로 작업을 하는 프로그램들 같은 경우 작업이 끝나면 다음 주기가 될 때까지 하드디스크로 가서 대기한다.
Parent process request
: 부모 프로세스는 자식 프로세스들을 일시적으로 중지시켰다가 다시 실행시킬 수 있다. 그래서 부모 프로세스가 요청을 하게 되면 자신의 자식 프로세스를 하드디스크로 쫓아낸다. 부모 프로세스는 자식 프로세스의 종료 상태를 확인하는 권한, 동기화, coordination 목적으로 중지시켰다가 다시 실행할 수 있다.
큐 안에는 프로세스의 포인터와 프로세스에 대한 간단한 정보만 들어있고 실제로 하드디스크로 쫓겨나는게 프로세스 자체이다.
Process Description
Primary Process Table
실행을 시작한 모든 프로세스들에 대한 정보들. Primary Process Table은 고정된 크기의 배열을 이용하므로 프로세스를 무한대로 생성할 수 없다.
- Process ID : 자신이 어느 위치에 있는지에 대한 정보 = 인덱스
- 프로세스 이미지에 대한 포인터
- 메모리 위치 : 프로세스가 메모리 어디에 위치해있는지에 대한 정보
Process Image

- 프로그램 영역 : 수정이 불가능한 또는 수정을 하지 않는 프로그램의 Instruction 영역 = 수정안하는 영역
- 데이터 영역 : 전역 변수, 스태틱 변수 등 변수들을 포함한 수정이 가능한 코드의 일부분 = 수정하는 영역
- 바이너리도 기계어 또는 어셈블리어로 프로그램을 작성하면 데이터만 수정할 수 있는 것이 아니라 명령어도 수정할 수 있다.
- 스택 : 실행을 시작하면 OS는 처음부터 스택 영역을 할당해둔다. 각각의 함수에서 사용하는 지역 변수, 함수를 마치고 리턴할 주소 등 에 대한 정보를 저장
- PCB : 프로세스를 OS가 관리하기 위해서 필요한 모든 정보들. OS가 PCB 영역을 만들고 관리한다. Supervisor 모드에서만 업데이트 가능한 영역이다.
Process Control Block
Process ID에 대한 정보
- Process ID
- Parent Process ID
- User ID = 실행시킨 사람의 User ID.
- 파일을 만든 사람 : A = 소유자
- 파일을 실행시킨 사람 : B = 이펙티브 유저
- 시스템에서는 누가 실행시킨 프로그램인지가 중요하다.
Processor State Information
(프로세스가 아닌 프로세서 = CPU)
- User-Visible Registers
- Control & Status Registers
- Program Counter
- Program Status Word(PSW)
- Stack Pointer
Process Control Information
- 스케쥴링 정보 : 우선순위를 결정을 하는데 필요한 정보들. CPU 사용 기간, 프로세스 종류 등등
- State 정보 : Ready, Running 등 상태 정보
- 메모리 매니지먼트 정보 : 프로세스가 어디에 있는지에 대한 정보와 메모리 조각들을 빠르게 찾기 위한 다양한 형태의 정보
- Resource ownership and utilization : 프로세스가 owner인 자원들(ex. 세마포, 메시지 큐 등)에 대한 정보 및 CPU, IO 장치, 메인 메모리, 자신이 만든 자원들을 얼마나 사용하는지에 대한 정보
- Process Privileges : 프로세스가 어떠한 권한을 가지고 있는지에 대한 정보
- Data Structuring : 큐, 프로세스 트리 등 형성되는 데이터 스트럭쳐

- Private User Address Space : 해당 유저의 프로그램 코드와 데이터. 프로그램 코드와 데이터는 컴파일 했을 때부터 있던 공간이다. 따라서 프로그램 코드와 데이터를 뜻한다.
- Shared Address Space : 여러 사람이 동시에 사용할 수 있는 영역
OS는 프로세스를 관리하는데 몇가지 중요한 작업이 있다.
- 프로세스를 어떻게 만들어냈는지
- 스위칭 작업
OS가 프로세스와 관련하여 해야 되는 작업들
- Process Management
- 프로세스 생성, 종료
- 스케쥴링, 디스패치 : Ready 큐에서 기다리는 프로세스들 중 어떤 프로세스를 선택해서 CPU를 할당할지와 해당 프로세스를 실행시키는 작업
- 스위칭 : OS가 하는 일 중에서 가장 중요한 작업
- 프로세스 동기화 및 Interprocess 커뮤니케이션 지원 : 동기화 툴을 지원하고, 프로세스 간 통신을 위해 파이프, 메시지 큐, 메모리 매핑 등 통신 툴을 제공
- PCB 관리 : PCB는 계속 변하는 정보이기 때문에 OS가 변하는 정보들을 계속 관리한다.
OS가 간섭한다는 말은 프로그램이 중단되고 OS가 실행한다
는 뜻이다.
- Memory Management
- 프로세스 공간 할당 : 메인 메모리, Swapping area
- Swapping : 언제 프로세스를 디스크에서 올리고 내릴지에 대한 결정
- Page와 segment 관리
- 페이지 단위로 자르는 경우 내용에 관계없이 동일한 크기로 자른다. 따라서 페이지를 바꿔가면서 실행하는 경우가 생긴다.
- 세그먼트 단위로 자르는 경우 프로그램 내용을 보고 자른다.
- I/O Management
- 버퍼 할당 : I/O 작업을 할 때 버퍼의 어디서부터 어디까지 쓸 수 있는지 할당
- I/O 디바이스를 할당 : 프로세스가 디바이스를 사용할 수 있게 허가하는 작업
- Support Functions
- 인터럽트 핸들링 : 위의 작업들을 하려면 수없이 OS가 끼어들어야 하는데 이는 수없이 인터럽트가 걸리거나 시스템 콜을 사용한다는 것이다.
- Accounting, Monitoring : 프로세스가 시스템 안에서 어떠한 자원들을 얼만큼 사용하는지에 대한 것들을 관리. 한마디로 OS는 프로세스가 실행을 시작해서 실행을 마칠 때까지 필요한 모든 작업들을 서비스 해준다.
Process Creation

A 프로세스가 OS한테 프로세스 생성 요청
- OS는 Process Id를 할당(= 프로세스 테이블에 새로운 엔트리 등록)
- 프로세스한테 공간 할당(= 사용할 수 있는 메인 메모리/swapping area 범위 할당 = 프로세스 생성 = 프로세스 이미지 생성, 프로그램 코드, 데이터, 스택, PCB까지 있어야 프로세스. 프로그램 코드와 데이터는 실행 파일에 다 들어있고, 스택 영역은 실행을 하면서 채워진다.)
- PCB영역 초기화( = 초기부터 필요한 정보들)
- 링크 연결 (= 프로세스 이미지는 프로세스 테이블에 연결, 메모리 상태에 맞는 큐 연결)
- 다양한 자료구조 생성
종료는 역순으로 진행되고 마지막에 엔트리를 남겨놓는다. 남겨놓는 이유는 부모 프로세스한테 확인을 받고 종료해야 하기 때문이다.
Switching
인터럽트가 발생하면 프로세스의 실행이 중단되고 OS가 작업한 후 다른 프로세스로 바뀔 수 있다. 이럴 때 A 프로그램에서 B 프로그램으로 바뀌면 프로세스 스위칭
이라 한다.
Process Switching
- 인터럽트 ⇒ 내가 원인이 돼서 발생한 인터럽트가 아니다.
- Clock(Timer) 인터럽트 : Running → Ready 상태로 간다.
- IO 인터럽트 : Running → Running / Running → Ready로 갈 수 있다.
- Memory Fault : 실행시켜야 하는 다음 명령 또는 데이터들이 하드디스크에 있어서 가져와야 할 때. 하드디스크도 I/O 디바이스다. 그래서 Blocked 상태로 간다.
- 트랩 = 프로그램 인터럽트 : 유저가 잘못한 경우. 경우에 따라 exit, running 상태로 보낸다.
- division by 0
- 다른 사람의 주소 읽기
- Supervisor call : OS 호출
- OS안에 있는 함수를 호출해서 OS 프로그램이 실행된다. Blocked 또는 Running 상태로 간다.
Mode Switching
A 프로그램 → OS → A 프로그램으로 변할때는 모드 스위칭
이라 한다.
- User Mode
- Kernel Mode
- OS 프로그램 실행
- 거의 완벽한 권한
- 메인 메모리에서 OS 영역뿐만 아니라 유저 영역들을 마음대로 엑세스 가능
Changes of Process State

- 실행하는 프로세스에 대한 작업
- 중단된 시점의 CPU안에 있는 레지스터 값들을 저장
- PCB의 Process Control Information(실행하고 있는 프로세스를 관리하기 위해 OS가 필요한 정보) 정보를 업데이트한다.
- 1) 레지스터 값 저장 + 2) PCB안에 있는 Process Control Information도 수정하기 때문에 시간이 많이 걸린다.
- 적절한 큐로 이동시킨다.
- 어떤 프로세스를 실행 시킬지에 대한 작업
- 어떤 프로세스를 실행시킬지 결정한다.
- 새롭게 실행할 프로세스의 PCB 중 Process Control Information을 업데이트한다.
- memory management(프로세스 테이블 관리)와 data structure를 업데이트한다.
- 새로 실행하는 프로세스의 PCB 안에 있는 정보 중 Processor State Information을 Restore한다.
Execution of OS
시스템 안에서 OS를 어떻게 실행시킬까?
Non-process Kernel

- 최근에 사용되는 방식이 아니라 굉장히 예전에 사용되던 방식
- 커널 크기가 크지 않기 때문에 커널 코드들이 전부 다 메인 메모리에 들어 있다.
- 커널 코드를 프로세스로 만들지 않고 그냥 실행, 유저 프로그램은 프로세스로 만들고 실행
- 커널 코드가 프로세스로 관리가 되지 않는다 = 인터럽트 핸들러, OS코드는 항상 메모리에 정해진 위치에 있다.
Execution Within User Processes

- 프로세스 안에 OS 함수가 들어가 있다.
- OS를 유저 프로세스의 컨텍스트 안에서 실행
- 프로세스 안에서 유저 프로그램 코드, 커널 코드를 실행할 수 있다.
- 인터럽트가 걸리면 인터럽트 핸들러가 Shared Address Space에 있다고 가정하고 필요한 변수들을 저장 공간을 커널 스택에 쌓는다.
- 유저 스택과 커널 스택을 가지고 있고, 유저 프로그램이 실행될 때는 유저 스택, OS 프로그램이 실행될 때는 커널 스택을 쌓아가며 작업한다.
Process-Based Operating System

- objected-orient 모델, 마이크로 커널 아키텍처 사용
- Switching Functions 부분 = 마이크로 커널
- 시스템이 유저 프로그램을 관리하는 방식 그대로 OS 프로세스들도 관리한다.
- OS들을 별개의 프로세스로 만들게 되면 확장성이 좋다.
- OS들이 다 별개의 프로세스로 구성되어 있기 때문에 각각의 CPU가 자기가 원하는 OS 작업을 실행시킬 수 있다. 따라서 여러 개의 프로세서를 가진 시스템에 적합한 설계 방법이다.
UNIX
- Execution WIthin User Processes 방식 사용 = OS 코드에 아주 많은 부분을 유저 프로세스 안에서 실행
- 모든 OS 코드를 유저 프로세스 안에서 실행하는 것은 아니다. 프로세스 단위로 관리되는 OS 코드들도 있다.
- 시스템 프로세스
- 0 : swapper
- 1 : init
- process tree
Process Description
유닉스가 관리하는 프로세스 이미지
- User Level Context = 유저 프로세스가 접근/업데이트 하는 공간
- 코드, 데이터, 유저 스택
- shared memory = 다른 프로세스랑 공유하는 데이터 공간
- Register Context = PCB의 Processor State Information
- 프로그램 실행을 중단했을 때 CPU안에 있는 레지스터의 값들을 저장해놓은 공간
- Program Counter
- Processor status register
- stack pointer
- General-purpose registers
- System Level Context = User ID, Process ID, Process Control Information(OS가 프로세스를 관리하기 위해 필요한 정보)
- 프로세스 테이블 엔트리(OS가 프로세스를 관리하는데 필요한 거의 모든 정보들) 관리
- U area (I/O 작업, 파일 작업과 같은 유저 프로세스의 컨텍스트 안에서 관리되어야 하는 것들)
- Per process region 테이블 : 메모리 관리 관련 내용. 프로세스가 차지하는 메모리의 위치, 메모리 영역 프로텍션 정보
- 커널 스택
UNIX Process State Transition Diagram

- create : 새로운 프로세스가 만들어지는 과정
- Ready to run in memory : 메모리 안에 충분한 공간이 있을 때
- Ready to run swapped = ready/suspend : 메모리 안에 공간이 없을 때
프로그램이 실행될 때 kernel running을 거치고 user running 상태가 된다.
user running에서 시스템콜을 사용하거나 인터럽트가 발생하면, kernel running으로 상태가 바뀌고 OS코드가 실행된다.
- Zombie : 프로그램 종료 후 프로세스 이미지까지 다 사라졌는데 테이블에 엔트리로만 남아있는 상태
- asleep in memory : running 상태에서 Blocked 상태
- sleep,swapped : swapping area에 있는 프로세스
- ready to run swapped : swapping area에 있다가 IO가 끝났을 때
sleep, swapped → asleep in memory로 갈 수 없다 = 하드디스크로 쫓겨나면 Block 문제가 해결되기 전까지 메모리로 다시 올리지 않는다.
러닝 상태가 2개인 이유 : 유저 프로세스 안에서 OS 코드가 실행되기 때문
- preempted : 타임아웃이 걸린 상황 = ready to run in memory.
- 둘이 구분된 이유는? preempted는 지금 당장 실행 가능한 프로세스이다.
💡 어떤 프로세스든지 프로세스가 실행을 시작하려면 OS가 프로세스의 실행을 시작시켜줘야 한다. 실제로 preempted 상태도 작업의 내용은 다르지만, OS가 작업을 해야만 user running 상태로 바뀐다.
그 이유는?
Blocked 상태로 가지 않기 때문에?
타이머 인터럽트는 당장이라도 CPU를 주면 실행할 수 있는데 타임아웃 때문에 멈췄다 = 지금 당장 실행 가능한 프로세스
Ready to run in Memory는 계속 실행을 할 수 없는 상태였던 프로세스들이 있다. blocked 상태였거나, 하드디스크에 있었거나, 새로 만들어진 프로세스다. 따라서 OS가 이 프로세스들에 대해서 추가로 프로세스의 Context 안에서 해야하는 작업들이 있다. 그래서 Ready to Run in memory 프로세스는 커널 러닝을 거쳐서 유저 러닝을 간다.
Preempted 상태의 프로세스는 그대로 다시 실행을 시키면 된다. 하지만 Ready to Run in memory 상태는 실행 시키기 전에 멈춰있던 상태들에 대한 작업을 먼저 해야 한다. 그래도 어떤 경우에도 커널 러닝 없이 바로 유저 러닝으로 갈 수 없다.
ready to run in memory의 프로세스들은 프로세스 컨텍스트에서 해야하는 작업이 존재한다. 따라서 해당 프로세스는 커널 러닝을 거쳐서 유저 러닝으로 간다.
하지만 preempted 상태의 프로세스는 직접 커널 러닝을 거쳐서 유저 러닝으로 가는게 아니라 OS 코드에 해당하는 시스템 프로세스가 작업을 해서 유저 러닝 상태가 된다. 따라서 OS가 작업을 하지만, preempted 상태에 있던 프로세스 내에서 해당 작업을 하는 것이 아니기 때문에 preemted 상태에서 유저 러닝 상태로 간다.