프로세스 관리
Process의 개념
- 초기의 컴퓨터는 한 번에 하나의 프로그램만을 처리했다.
- 이 프로그램은 cpu, 메모리 등의 리소스들을 혼자 독차지했다.
- 이 프로그램은 리소스들의 접근에 대해 제한이 없었다.
- 이제는 컴퓨터가 발전되어 한 번에 여러개의 프로그램을 메모리에 올려서 처리하게 되었다.
- 이 때문에 프로세스라는 개념이 생겨났다.
- 컴퓨터 시스템에서 하나의 작업 단위이다.
- 실행중인 프로그램을 뜻한다.
- 멀티 프로세스로 인해서 각각의 프로세스에 대한 통제가 필요하게 되었다.
- 이 때문에 프로세스라는 개념이 생겨났다.
프로세스의 상태
- New
- 프로세스가 새로 생성된 상태
- 프로그램이 메인 메모리로 올라온 상태
- Ready
- 실행 준비가 완료된 상태
- CPU 할당을 받을 수 있으나, 아직 기다리는 상태이다.
- Running
- CPU를 점유중인 상태
- I/O 작업 등을 만나면, CPU 점유를 넘기고 Waiting 상태로 바뀐다.
- 시분할 프로그래밍으로, CPU 점유를 넘기고 Ready 상태로 바뀐다.
- 프로세스의 작업이 끝나면, Terminated 상태로 바뀐다.
- Waiting
- I/O 작업 등으로 CPU 점유를 넘기고 대기중인 상태
- 다른 작업으로 CPU 할당을 받지 않는 상태이다.
- I/O 작업이 끝나면 Ready 상태로 바뀐다.
- Terminated
- 프로세스가 종료된 상태이다.
PCB
- Process Control Block
- 운영체제가 프로세스를 관리하기 위한 정보를 담아두는 곳이다.
- 프로세스 상태 정보
- PC (Program Counter)
- 레지스터 정보
- 메모리 내에서 번지 수 (base, limit)
- CPU 점유 시간
- PID (Process ID)
- list of open files (해당 프로세스가 사용하는 파일들)
- 등등 …
- 하나의 프로세스 당 하나의 PCB를 생성해서 가진다.
- 문맥 교환 시에 처리 중이던 프로세스를 PCB에 저장하여 다음 차례 때 꺼내서 쓴다.
프로세스 스케쥴링
- 멀티 프로그래밍의 목적은 프로세스를 여러개 올려서 CPU 활용도를 최대화하기 위함이다.
- 시분할 시스템의 목적은 프로세스 간에 CPU를 자주 전환하여 사용중인 프로세스 간의 상호 작용을 얻기 위함이다.
- 그러나 결국 CPU의 코어 하나는 한 번에 하나의 프로세스만을 처리할 수 있다.
- 위와 같은 목적을 달성하기 위해 프로세스 스케쥴링이 필수이다.
- 프로세스 스케쥴링이란 결국 실행해야 하는 프로세스 목록에서 처리할 하나의 프로세스를 고르는 과정이다.
프로세스 큐
- 여러 개의 프로세스를 처리해줘야 하니까 그때마다 동시에 모든걸 처리할 수는 없다.
- 처리하려는 프로세스들은 대기열에 들어가고
- 대기열에서 적절한 프로세스를 올려 처리한다.
- 프로세스들이 기다리는 대기열을 프로세스 큐라고 한다.
- 또 I/O bound 프로세스와 CPU bound 프로세스의 균형있는 처리를 맡는다.
- I/O bound 프로세스는 I/O 작업을 많이하는 프로세스
- CPU bound 프로세스는 CPU 작업을 많이하는 프로세스
- I/O 작업에 치중된 프로세스들만 가득하다면 CPU는 놀게 된다.
- CPU 작업에 치중된 프로세스들만 가득하다면 CPU 처리가 늦어지게 된다.
각 기기 사이마다 존재하는 프로세스 큐는 아래와 같다.
- Job Queue
- 서브 메모리에서 메인 메모리에 올라가기를 기다리는 큐이다.
- Ready Queue
- 프로세스들이 CPU 할당을 기다리는 큐이다.
- Device Queue
- I/O 장치를 사용하기 위해 기다리는 큐이다.
- 각각의 I/O 장치당 하나의 큐가 있다.
스케줄러는 다음과 같이 나눌 수 있다.
- Long-term Scheduler
- Ready Queue로 갈 프로세스를 선택한다.
- 메모리에 적재할 프로세스의 수를 제어한다.
- 간단하게 말하면 메모리에 적재할 프로그램을 선별하는 애다.
- Short-term Scheduler
- 다음 실행될 프로세스를 선택하여 CPU에 적재한다.
- 간단하게 다음에 처리할 프로세스를 골라주는 애다.
- Medium-term Scheduler
- 얘도 메모리에 올라가 있는 프로세스의 수를 제어하는건 똑같은데,
- 이미 올라간 프로세스를 내려서 줄이는 역할을 한다.
- 잘 쓰이지 않는 애들을 내려서 쉬게 하다가, (swap-out)
- 다시 쓰일 때 슬그머니 올려준다. (swap-in)
- 역할 때문에 Swapper라고도 부른다.
- 얘도 메모리에 올라가 있는 프로세스의 수를 제어하는건 똑같은데,
Context Switching
- 우리말로 문맥 교환이라고도 한다.
- 현대의 운영체제는 대부분 시분할 시스템을 갖고 있다.
- 시분할 시스템은 겉으로 보기에는 여러개의 프로세스를 동시에 수행하는 것 같지만,
- 사실은 CPU를 여러 프로세스가 조금씩 아주 빠르게 돌려가며 사용하는 것이다.
- 이때 처리 중이던 프로세스에서 다른 프로세스로 CPU 점유가 넘어가는 것을 문맥 교환이라고 한다.
- CPU가 처리하던 프로세스의 정보를 PCB에 저장해두고,
- 다른 새로운 프로세스의 PCB를 참조하여 다시 처리를 시작한다.
- 이것을 빠르게 반복한다.
문맥 교환에 고려해야 할 것들은 다음의 것들이 있다.
- 다음에 어떤 프로세스로 스위칭 해야하는가
- 스위칭 시에 일어나는 오버헤드를 어떻게 줄일 것인가
CPU 스케쥴링
- 현재 프로세스가 끝나면, 다음에 어떤 프로세스를 처리해야 하는가를 결정하는 것이 CPU 스케쥴링이다.
- Preemptive vs Non-preemptive
- CPU 스케쥴링 알고리즘은 두 가지로 나눌 수 있다.
- 선점 vs 비선점
- 선점
- 현재 프로세스가 끝나거나, I/O 작업을 만나지 않았는데
- 다른 프로세스가 스윽 뺏을 수 있는 방식
- 비선점
- 현재 프로세스가 끝나거나, I/O 작업을 하지 않는 이상 절대 양보를 안하는 방식
- 선점
- 스케쥴링의 효율성을 나타내는 척도는 다음과 같은 것들이 있다.
- CPU Utilization
- CPU 이용률
- CPU가 얼마나 놀지 않고 계속 일했는가
- Throughput
- 처리율
- 시간 당 작업 처리 수
- Turnaround time
- 반환 시간
- 프로세스가 준비된 후부터 처리가 완료되어 종료되는 시점까지의 시간
- Waiting time
- 대기 시간
- CPU 점유를 위해 프로세스가 Ready Queue에서 대기한 시간
- Response time
- 응답 시간
- 프로세스가 준비된 후부터 첫 CPU 점유를 받았을 때까지 걸린 시간
- CPU Utilization
FCFS
- First Come First Served
- 먼저 온 놈 먼저 처리해주겠다는 뜻
- 가장 간단하고 공평한 방식이다.
- 비선점 알고리즘이다.
프로세스 | 도착시간(s) | 처리시간(s) |
---|---|---|
P1 | 0 | 20 |
P2 | 0 | 8 |
P3 | 0 | 8 |
- P1, P2, P3가 동시에 와서, P1-P2-P3 순으로 처리를 해주었다.
- AWT (Average Waiting Time)을 구해보면,
- (0 + 20 + 28) / 3 = 16
- 한 사람 당 평균적으로 16초나 기다렸다.
- P1이 너무 오래 걸려서 P1을 맨 뒤로 보냈다. 짧은 애들을 먼저 처리해본다.
- P2-P3-P1
- AWT를 구해보면,
- (0 + 8 + 16) / 3 = 8
- 한 사람 당 평균적으로 8초만 기다리면 된다.
- 이게 훨씬 더 효율적인 것을 알 수 있다.
SJF
- Shortest Job First
- 짧은 놈을 먼저 처리하겠다는 뜻
- 증명된 최적화 알고리즘이다.
- 그러나 현실적이지 못하다.
프로세스 | 도착시간(s) | 처리시간(s) |
---|---|---|
P1 | 0 | 12 |
P2 | 0 | 16 |
P3 | 0 | 14 |
P4 | 0 | 6 |
- 먼저 위의 작업을 먼저 도착한 작업을 먼저 처리하는 FCFS로 처리해본다.
- AWT를 구하면,
- 동시에 왔으나 처리 시간을 고려하지 않고, P1-P2-P3-P4 순으로 처리했다고 가정한다.
- (0 + 12 + 28 + 42) / 4 = 20.5
- 한 사람 당 평균적으로 20.5초나 대기해야 한다.
- 먼저 온 작업을 먼저 처리하는 SFJ로 처리해본다.
- AWT를 구하면,
- (0 + 6 + 18 + 32) / 4 = 14
- 한 사람 당 평균적으로 14초만 대기하면 된다.
SJF를 증명된 최적화 알고리즘이나, 현실적이지 못한 방법이라고 했었다.
- SJF는 수학적인 계산으로는 가장 대기 시간을 줄일 수 있는 방법이다.
- 그러나 위의 예시들처럼 항상 프로세스의 처리 시간을 정확하게 알지 못한다.
- 그러니 이 방법은 프로세스의 처리 시간이 얼마나 될 것이라는 예측을 정말 잘해야 한다.
- 근데 예측을 위한 오버헤드가 부담이 되기 때문에 역시 현실적이지 못하다.
프로세스 | 도착시간(s) | 처리시간(s) |
---|---|---|
P1 | 0 | 16 |
P2 | 1 | 8 |
P3 | 2 | 18 |
P4 | 3 | 10 |
- 먼저 위의 표를 비선점 SJF 알고리즘으로 처리해본다.
- P1-P2-P4-P3 순으로
- 먼저 처리 중이던 프로세스가 끝나면,
- 다음으로 가장 짧은 프로세스의 처리를 시작한다.
- AWT를 구해보면,
- (0 + 16 + 24 + 34) / 4 = 18.5
- 평균적으로 18.5초나 기다려야 한다.
- 이번엔 선점 SJF 알고리즘으로 처리해본다.
- 먼저 도착한 순서대로 처리를 시작하지만,
- 그 뒤에 도착한 작업의 길이가 더 짧다면
- 더 짧은 작업을 우선 처리한다.
- 처리 순서는 다음과 같다.
- P1이 0초에 도착해 처리를 시작한다. (0초)
- P2가 1초에 도착해 CPU를 선점한다. (1초)
- P1은 (16-1)초 남았고, P2는 8초이기 때문에 더 짧은 P2가 선점한다.
- P3가 2초에 도착했지만, 더 짧은 P2를 처리 중이라 선점하지 못한다.
- P4가 3초에 도착했지만, 더 짧은 P2를 처리 중이라 선점하지 못한다.
- P2의 작업이 모두 끝나고, 지금 시점에 가능한 가장 짧은 P4의 처리(10초)를 시작한다. (9초)
- P4의 작업이 모두 끝나고, 지금 시점에 가능한 가장 짧은 P1의 처리(16-1초)를 시작한다. (19초)
- P1의 작업이 모두 끝나고, 남아있는 P3의 처리(18초)를 시작한다. (34초)
- 작업이 모두 끝난다. (52초)
- AWT를 구해보면,
- P1의 총 대기 시간: 8
- P2의 총 대기 시간: 0
- P3의 총 대기 시간: 32
- P4의 총 대기 시간: 6
- (8 + 0 + 32 + 6) / 4 = 11.5
- 평균적으로 7초나 덜 기다려도 된다.
우선 순위 스케쥴링
- Priority Scheduling
- 우선 순위가 빠른 녀석을 먼저 처리하겠다는 뜻
- 빠르다고 표현한건 priority가 작은 애가 우선이기 때문에
- 얘도 역시 선점, 비선점이 있다.
프로세스 | 처리시간(s) | 우선순위 |
---|---|---|
P1 | 10 | 3 |
P2 | 1 | 1 |
P3 | 2 | 4 |
P4 | 1 | 5 |
P5 | 5 | 2 |
- 우선 순위가 빠른 친구부터 먼저 처리한다.
- 전부 동시에 도착했다고 가정한다.
- AWT를 구해보면,
- (6 + 0 + 16 + 18 + 1) / 5 = 8.2
그럼 우선 순위는 어떤 식으로 결정하는 걸까
- internal
- time limit
- 작업 처리 시간 적은 거 우선
- memory requirement
- 메모리 사용량 적은 거 우선
- I/O to CPU burst
- I/O 작업 시간과 CPU 작업 시간을 비교해서 결정
- time limit
- external
- amounts of funds being paid
- 돈 많이 낸 놈 우선 결정
- political factors
- 정치적 요소로 중요한 거 우선 결정
- amounts of funds being paid
우선 순위 알고리즘의 문제점
- starvation
- 기아 현상이라고도 한다.
- 우선 순위가 계속 밀려나면서 CPU 점유를 받지 못하는 경우를 기아 현상이라고 한다.
- 위의 우선 순위 예시에서는 프로세스가 몇 개 없었지만, 실제로는 계속해서 프로세스가 큐에 추가된다.
- 예를 들어, 위에서 우선 순위가 가장 낮았던 P4는
- 자기보다 빠른 우선 순위를 가지는 작업이 4개 밖에 없기 때문에
- ‘언젠가는 내 차례가 오겠지 ㅎㅎ’ 라고 생각한다.
- 그러나 계속 다른 우선 순위가 P4보다 작은 작업들이 추가되고,
- P4가 계속 밀리고 밀려 CPU 점유를 받지 못하는 경우가 생길 수 있다.
- aging
- starvation을 해결하기 위한 방법이다.
- 레디 큐에서 우선 순위가 계속 밀리는 작업들에 나이를 매겨 우선 순위를 높여주는 방식이다.
Round-Robin
- 시분할 시스템을 위한 알고리즘
- 작업의 우선 순위를 두지 않고
- 일정 시간을 정해서
- Time Quantum (Time Slice)
- 각각의 프로세스들을 돌아가며 처리하는
- 선점형 알고리즘이다.
- 작업 도중에 뺏고를 반복하기 때문에 비선점일 수가 없다.
프로세스 | 처리시간(s) |
---|---|
P1 | 24 |
P2 | 3 |
P3 | 3 |
- Time Slice가 4s일 떄,
- AWT를 구해보면,
- (6 + 4 + 7) / 3 = 약 5.67
- Time Slice가 1s일 떄,
- AWT를 구해보면,
- (6 + 5 + 6) / 3 = 약 5.67
- Time Slice가 30s일 때,
- AWT를 구해보면,
- (0 + 24 + 27) / 3 = 17
- Time Quantum을 어떻게 나누냐가 중요하다.
- 너무 길게 잡았더니,
- 위의 예시에서 보면 FCFS 알고리즘과 다를게 없었다.
- 너무 짧게 잡는다면,
- 문맥 교환시에 발생하는 오버헤드가 너무 잦아진다.
- 위의 예시에서 보면 Time Slice가 4s인 경우랑 1s인 경우에 AWT가 같았다.
- 결국 문맥 교환이 적게 일어나는 4초의 경우가 훨씬 이득이다.
- 너무 길게 잡았더니,
- 일반적으로는 10ms ~ 100ms 사이의 값으로 잡는다고 한다.
Multilevel Queue Scheduling
- 프로세스의 종류나 목적에 따라서 여러 개의 프로세스 그룹을 두고 각각의 프로세스 그룹에 우선 순위를 정해둔다.
- 프로세스 그룹은 이런식으로 나눌 수 있다.
- System Process
- Interactive Process
- Batch Process
- Student Process
- 각각 나뉜 프로세스 그룹마다 큐를 두고, 그 싱글 큐마다 또 다른 스케쥴링 정책을 적용한다.
Multilevel Feedback Queue Scheduling
- 얘도 역시 여러 개의 큐를 놔두고 각각 다른 정책을 사용하는 것은 똑같다.
- 그러나 얘는 그룹을 나누지 않는다.
- 모든 프로세스는 다 같은 입구로 들어온다. (첫 번째 큐)
- 어느 한 프로세스가 너무 많은 CPU time 사용 시에 다음 큐로 보낸다.
- 기아 상태가 우려될 시에 다시 우선 순위 높은 큐로 보낸다.
프로세스 생성과 종료
프로세스의 생성
- 프로세스는 프로세스에 의해 만들어진다.
- 부모 프로세스
- 다른 새로운 프로세스를 생성한 프로세스
- 자식 프로세스
- 다른 프로세스에 의해 생성된 새로운 프로세스
- 프로세스 트리
- 어떤 프로세스가 생성한 모든 자손들을 그린 가계도
- 부모 프로세스
- 가장 첫 번째 프로세스
- 컴퓨터가 부팅되고, 운영체제를 로드하려 한다.
- 운영체제의 가장 첫 번째 하나의 프로세스를 생성한다. (init)
- 그 init 프로세스가 다른 자식 프로세스들을 생성한다.
- 역시 자식들도 자식 프로세스들을 주주죽 생성한다.
- PID
- Process Identifier
- 각 프로세스에 부여된 고유 식별자 (init은 보통 0)
- 부모의 PID를 PPID라고 한다.
- 그럼 생성은 어떻게 하는가?
- 새로운 프로세스를 만드는 시스템 콜인 fork()를 호출한다.
- 새로 만들어진 프로세스를 동작하게 하는 exec() 시스템 콜을 호출한다.
- 프로세스 종료
- 종료하려는 프로세스가 exit() 시스템 콜을 호출한다.
- 종료되는 프로세스가 사용하던 모든 리소스가 반납된다.
- 메모리, 파일 등
쓰레드
- Thread
- 한 프로그램 내부의 흐름
- 하나의 쓰레드만을 가지는 프로그램을 단일 쓰레드 프로그램이라고 한다.
- Multi Threads
- 한 프로그램 내부에 여러 개의 쓰레드(흐름)이 존재하는 것
- 다중 쓰레드 프로그램
- 두 쓰레드를 빠르게 스위칭 하면서 마치 동시에 실행되는 것처럼 보인다.(Concurrent)
- Concurrent vs Simultaneous
- Concurrent는 시간 간격을 두고 번갈아 가며 수행해서, 동시에 수행하는듯 보이게 하는 것
- Simultaneous는 실제로 동시에 수행하는 것
- Concurrent vs Simultaneous
- 한 프로그램 내부에 여러 개의 쓰레드(흐름)이 존재하는 것
- 멀티 쓰레드 내부 구조는
- 프로세스의 메모리 공간을 공유한다.
- 프로세스의 자원을 공유한다.
- 레지스터나 스택은 서로 공유하지 않는다.
This post is licensed under CC BY 4.0 by the author.