[Ch06 고급 프로세스 관리]
- 5장에서는 프로세스가 무엇인지, 생성, 제어, 종료에 관한 시스템 콜과 관련된 시스템에 대해 알아봤음.
- 이번 장에서는 리눅스 프로세스 스케줄러와 스케줄링 알고리즘을 알아본다.
6.1 프로세스 스케줄링
- 프로세스 스케줄러는 커널의 서브 시스템으로써 유한한 리소스인 프로세서의 시간을 시스템 내의 프로세스에 나눠준다.
- 즉, 다음에 실행할 프로세스를 선택하기 위한 커널의 구성요소임.
- 실행 가능한 프로세스
- 블록되지 않은 프로세스
- 블록된 프로세스
- 자고 있거나, 커널로부터 입출력을 기다리고 있는 프로세스
프로세서의 개수보다 실행 가능한 프로세스가 더 많이 존재할 때는 스케줄러가 필요함
- 선점형 멀티태스킹
- 리눅스
- 다른 프로세스를 위해 실행 중인 프로세스를 멈추는 행위를 선점이라고 함.
- 스케줄러가 선점하기 전까지 프로세스에 허락된 실행 시간을 프로세스 타임 슬라이스라고 한다.
- 비선점형 멀티태스킹
- 프로세스가 스스로 실행을 멈추기 전까지 계속 실행함.
- 자발적으로 실행을 잠시 쉬는 것을
양보
라고 함 - 너무 오래 실행되는 그런 단점때문에 최신 OS는 거의 선점형 을 사용한다.
6.1.1 타임 슬라이스
- 스케줄러가 각 프로세스에 할당하는 타임 슬라이스는 시스템 전반의 동작 방식과 성능에 관한 중요한 변수이다.
- 타임 슬라이스가 너무 크다면 프로세스는 다음 실행 시간까지 오래 기다려야 하며, 동시 수행 능력을 떨어트림.
- 반대로 너무 작으면 잦은 프로세스 전환으로 인해 일시적인 지역성과 같은 장점을 잃게 됨.
- 목적에 따라 크기를 다르게한다.
- 시스템이 처리할 수 있는 용량을 극대화하여 성능 향상을 하려고 큰 슬라이스를 사용함.
- 혹은 빠른 응답속도를 확보하기 위해서 작은 슬라이스를 사용함.
- → 이상적인 사이즈를 결정하기가 어려움!
6.1.2 입출력 위주 프로세스와 CPU 위주 프로세스
- 사용 가능한 타임 슬라이스를 끊임없이 계속 사용하는 프로세스를 CPU 위주 프로세스라고 한다.
- 스케줄러에서 허락하는 시간을 모두 사용함
예시
- 무한루프
- 과학계산, 수학연산, 이미지 처리 등
1 2 3
// 100% processor-bound while (1) ;
실행 시간보다 리소스를 사용하기 위해 기다리는 시간을 더 많이 사용하는 프로세스를 IO 위주 프로세스 라고 한다.
- 네트워크 입출력, 파일 입출력 기다림.
- cp, mv 같은 파일 유틸리티 , User GUI 등.
- 각각의 특성에 맞게 스케줄러를 선택해야함.
- CPU 위주
- 일시적인 지역성을 통해 캐시 적중률을 최대화하고 작업을 빨리 끝내기 위해 큰 타임 슬라이스를 사용
IO 위주
- 입출력 요청을 보내기까지 아주 짧은 시간이면 충분하고 대부분의 시간을 커널 리소스를 얻기 위해 블록되기 때문에 큰 슬라이스가 필요없음.
- 현실에서는 CPU와 입출력을 같이 사용함
6.1.3 선점형 스케줄링
- 전통적인 유닉스 프로세스 스케줄링에서 모든 실행 가능한 프로세스는 타임 슬라이스를 할당받음
- 프로세스가 주어진 타임 슬라이스를 다 소진하면 커널은 그 프로세스를 잠시 멈추고 다른 프로세스를 실행.
- → 모든 프로세스는 자신보다 우선순위가 높은 프로세스가 있을지라도 그 프로세스가 타임 슬라이스를 모두 소진하거나 블록된다면 결국 실행될 기회를 얻게됨.
- → 모든 프로세스는 반드시 계속 진행되어야 한다는 규칙을 만들어냄
6.2 CFS 스케줄러
- Completely Fair Scheduler
- CFS 전의 전통 유닉스 시스템들은
우선순위
와타임 슬라이스
라는 변수를 사용해서 스케줄링을 구현했음 - CFS는 타임 슬라이스 대신 CPU 시간의 일부를 각 프로세스에 할당한다.
- N개의 프로세스에 각각
1/N
만큼의 CPU 시간을 할당한다. - 그리고 이를 각 프로세스의
nice
값에 따라 가중치를 준다. nice
값이 기본값인0
을 그대로 사용하는 프로세스의 가중치는1
이며, 따라서 할당받는 CPU 시간에는 변화가 없다.- 기본값보다 적은 nice 값을 사용하는 (우선순위가 높은) 프로세스는 CPU 시간을 더 많이 할당 받음
- N개의 프로세스에 각각
- 각 프로세스가 수행될 시간을 결정하기 위해 CFS 스케줄러는 프로세스 별로 가중치가 적용된 값을 한정된 시간(
Target Latency
) 로 나눈다.- 시스템의 스케줄링 레이턴시를 나타냄.
- 예시
- Target Latency : 20 밀리초
- 5개의 프로세스
- → 각 4밀리초
- But, 프로세스가 많다면 Context Switching Overhead 때문에 일시적인 지역성의 효과는 줄어들고 시스템 전체 처리 성능은 매우 지장받음
- →이런 상황을 피하기 위해 CFS는 최소단위 (
Minimum Granularity
) 를 사용함
- →이런 상황을 피하기 위해 CFS는 최소단위 (
- 최소 단위
- 프로세스가 실행되는 최저 시간 단위
- 모든 프로세스는 할당된 CPU 시간과 관계없이 최소 단위만큼은 실행된다는 의미
- 근데 이를 사용하면 공정성이 무너짐!
- → 납득할 수 있는 만큼의 평범한 상황에서는 최소 단위가 적용되지 않고, Target latency 만으로 공정성을 유지할 수 있다.
6.3 프로세서 양보하기
- 리눅스는 선점형 멀티태스킹 운영체제지만, 프로세스가 명시적으로 실행을 양보해서 스케줄러가 새로운 프로세스를 실행하도록 하는 시스템 콜을 제공한다.
1
2
3
#include <sched.h>
int sched_yield (void);
- sched_yield() 를 호출하면 현재 실행 중인 프로세스를 잠시 멈춘 다음 스케줄러가 다음에 실행할 새로운 프로세스를 선택하도록 한다.
- 다른 실행 가능한 프로세스가 없으면 sched_yield() 를 호출한 프로세스의 실행이 즉시 재개됨.
- → 이런 불확실성과 일반적으로 더 나은 대안에 대한 믿음 때문에 이 시스템 콜은 잘 안씀.
6.3.1 적당한 사용법
- 리눅스 커널은 가장 효율적이고 최적의 스케줄링 결정을 내리기에 부족함이 없음
- → 일개 어플리케이션이 무엇을 언제 선점해야 할지 결정하는 것보다 커널이 훨씬 더 나은 결정을 할 수 있음 !!
- 쓰는 경우가 있긴 하지만 잘 안씀.
6.4 프로세스 우선 순위
- nice 값은 프로세스가
be nice
하기를 바라면서 만들어짐. - -20 ~ 19 의 값을 가지고 있다.
- 값이 높을 수록 Nice 하기때문에 우선순위가 낮음.
6.4.1 nice()
1
2
3
#include <unistd.h>
int nice (int inc);
- 호출이 성공하면 프로세스의 nice 값을 inc로 지정하고 새롭게 업데이트 된 값을 리턴한다.
- 오직
CAP_SYS_NICE
값을 가진 프로세스만 negative 값을 받을 수 있다.- 보통 root 만 이럼.
- 결과적으로 non root 프로세스는 오직 우선순위를 낮출 수만 있음.
- 예시
1 2 3 4 5 6 7 8
int ret; errno = 0; ret = nice (10); /* increase our nice by 10 */ if (ret == −1 && errno != 0) perror ("nice"); else printf ("nice value is now %d\n", ret);
- inc 값에 0을 넣으면 프로세스의 현재 nice 값을 알 수 있다.
6.4.2 getpriority() 와 setpriority()
1
2
3
4
5
#include <sys/time.h>
#include <sys/resource.h>
int getpriority (int which, int who);
int setpriority (int which, int who, int prio);
which
- PRIO_PROCESS
- PRIO_PGRP
- PRIO_USER
- 각각 who 값이 pid, pgid, uid를 판단한다.
- 만약 who 가 0이면 현재 pid,pgid, uid를 받아옴.
getpriority()
는 지정된 프로세스들 중에서 가장 높은 우선순위를 리턴함.setpriority()
는prio
값으로 특정된 프로세스들 전부를 지정함.- 예시
- 현재 프로세스의 우선순위를 출력한다. ```c int ret;
ret = getpriority (PRIO_PROCESS, 0); printf (“nice value is %d\n”, ret);
1 2 3 4 5 6 7
- 현재 프로세스 그룹의 전체 프로세스의 우선순위를 10으로 지정한다. ```c int ret; ret = setpriority (PRIO_PGRP, 0, 10); if (ret == −1) perror ("setpriority");
6.4.3 I/O 우선순위
- 기본적으로 I/O 스케줄러는 프로세스의 nice 값을 기준으로 I/O 우선순위를 결정한다.
1
2
int ioprio_get (int which, int who)
int ioprio_set (int which, int who, int ioprio)
- glibc 는 지원하지 않음.
6.5 프로세서 친화
- 리눅스는 싱글 시스템에서 멀티프로세서를 지원함.
- 멀티프로세싱 머신에서 프로세스 스케줄러는 어떤 프로세스가 각 CPU에서 돌 것인지 판단해야만 한다.
- 프로세스가 놀 동안 CPU가 놀고 있으면 안됨.
- 프로세스가 한 CPU에 스케줄링 되고 다음에 다시 스케줄링 될 때 같은 CPU에 되어야함.
- migrating 부분에서 이점이 있음
- 가장 큰 비용은 migration 할 때 캐쉬의 영향이다.
- 프로세스 스케줄러는 프로세스를 특정 CPU에 오랫동안 두어야함.
6.5.1 sched_getaffinity() 와 sched_setaffinity()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define _GNU_SOURCE
#include <sched.h>
typedef struct cpu_set_t;
size_t CPU_SETSIZE;
void CPU_SET (unsigned long cpu, cpu_set_t *set);
void CPU_CLR (unsigned long cpu, cpu_set_t *set);
int CPU_ISSET (unsigned long cpu, cpu_set_t *set);
void CPU_ZERO (cpu_set_t *set);
int sched_setaffinity (pid_t pid, size_t setsize,
const cpu_set_t *set);
int sched_getaffinity (pid_t pid, size_t setsize,
cpu_set_t *set);
sched_getaffinity()
는 프로세스 pid의 CPU 친밀도를 얻고cpu_set_t
타입의 값에다가 저장한다.- 만약 pid가 0이면 호출은 현재 프로세스의 affinity를 얻어옴.
setsize
는cpu_set_t
타입인데 타입의 사이즈 변화에 사용된다.- 예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
cpu_set_t set; int ret, i; CPU_ZERO (&set); ret = sched_getaffinity (0, sizeof (cpu_set_t), &set); if (ret == −1) perror ("sched_getaffinity"); for (i = 0; i < CPU_SETSIZE; i++) { int cpu; cpu = CPU_ISSET (i, &set); printf ("cpu=%i is %s\n", i, cpu ? "set" : "unset"); }
- 현재 프로세스의 affinity 를 출력한다.
1 2 3 4 5 6
cpu=0 is set cpu=1 is set cpu=2 is unset cpu=3 is unset ... cpu=1023 is unset
- 두개의 프로세스가 돌아가는 상태일 때의 출력값
- 만약 0,1 중에서 0만 쓰고 싶다면,, ```c cpu_set_t set; int ret, i;
CPU_ZERO (&set); /* clear all CPUs / CPU_SET (0, &set); / allow CPU #0 / CPU_CLR (1, &set); / disallow CPU #1 */ ret = sched_setaffinity (0, sizeof (cpu_set_t), &set); if (ret == −1) perror (“sched_setaffinity”);
for (i = 0; i < CPU_SETSIZE; i++) { int cpu;
1 2 3 4 5 6 7
cpu = CPU_ISSET (i, &set); printf ("cpu=%i is %s\n", i, cpu ? "set" : "unset"); } ``` # 6.6 실시간 시스템 - 실시간 : Time Limit 이 존재함. - Low latency or 빠른 응답시간 : 빠르면 빠를수록 좋은 것 - 예제 - Task A는 특정 기능을 1초안에 수행하지 않으면 전체 시스템에 치명적인 위해를 가할 수 있음. - → Time limit : 1초. - → 1초라는 시간을 준수하면서 특정 기능을 수행하는 것을 `실시간`이라고 함 - Task B는 기능을 수행함에 있어 Time Limit 은 없다. - → 빠르면 좋긴하겠지만 느리다고 해서 치명적인 손상을 입히는 것은 아님. - 리눅스 기반의 Real-time OS - 리눅스 기반의 RTOS와 일반 리눅스 OS는 크게 차이가 없다. - 모든 OS는 preemptive 한 작업 수행을 보장함. - **일반 리눅스는 interrupt가 들어왔을 때 현재 수행 중인 시스템 콜을 끝낸 뒤 Context switching**이 일어나지만, **RT 커널 기반의 리눅스는 현재 작업 중인 프로세스의 시스템 콜 수행마저도 Interrupt를 걸어 작업 Switching에 대한 Latency를 최소화**한다
- 현재 프로세스의 affinity 를 출력한다.
- 일반 프로세스 레벨에서는 nice/renice를, RT 프로세스에서는 chrt를 쓰면됨.
6.6.1 Hard Real-Time VS Soft Real-Time System
- hard real-time system
- os의 데드라인을 무조건 따라야함.
- 데드라인을 넘어서는것은 제약적인 실패이고 큰 버그를 야기함.
- 예제
- ABS 시스템, 총기 시스템, 의료 장비, 시그널 프로세싱..
- soft real-time system
- 데드라인을 넘는 것을 크리티컬하다고 생각하지 않음.
- 예제
- 비디오 프로세싱 애플리케이션
- 데드라인이 넘어서 조금의 프레임이 깨져도 크게 영향이 없다.
- 비디오 프로세싱 애플리케이션
6.6.2 Latency, Jitter and Deadlines
- Latency
- 잠재적 시간 지연
- 응답에 대한 실행이 나타나기 까지의 시간을 의미
- 지연이 os 데드라인보다 작거나 같다면 잘 동작하는 것이다.
- Jitter
- 응답간의 시차
- 지연 요소의 변동량. 즉, Latency 나 delay의 변화량 수준
- 연속적인 이벤트 간의 시간 편자는 레이턴시가 아니라 지터임.
6.6.3 Linux’s Real-Time Support
- 리눅스는 시스템 콜을 지원하여서 soft real-time 애플리케이션을 지원한다.
6.6.4 Linux Scheduling Policies and Priorities
- 리눅스는 두가지 스케줄링 정책을 제공함.
-
로부터 매크로를 제공받는다. SCHED_FIFO
,SCHED_RR
,SCHED_OTHER
- 모든 프로세스들은 nice 값이랑 별개로 static priority 를 가지고 있음.
- 기본적으로 0이다.
- 실시간 프로세스에서는 1-99까지의 값을 가진다.
- 일반적으로
SCHED_OTHER
를 사용함- 기본적으로 여러 프로세스 간 Time-sharing 방식(CFS Scheduler) 또는 우선순위 기반 스케줄링을 사용.
- FIFO, RR
- RT를 위한
FIFO 전략
- FIFO는 timeslices가 없는 매우 심플한 실시간 전략이다.
- 더 높은 우선순위를 가진 프로세스가 없는 한 계속 진행한다.
SCHED_FIFO
매크로를 사용함- 정책에 타임슬라이스가 없기 때문에 비교적 간단하다.
- 프로세스가 가장 높은 우선순위에 있다면 항상 실행됨.
- 프로세스가 블록되거나
sched_yield()
가 실행되거나, 더 높은 우선순위의 프로세스가 들어오기 전까지 계속 실행됨.
- Q) 같은 우선순위의 프로세스들이 있다면?
Rount-Robin 전략
- FIFO 클래스와 동일하지만 같은 우선순위일 때 추가적인 전략들이 있다.
SCHED_RR
매크로를 사용- 스케줄러는 RR-classed 프로세스 각각에 타임 슬라이스를 배정한다.
- 프로세스가 자신의 타임슬라이스를 다 쓰면 스케줄러는 그 프로세스를 우선순위 리스트에 끝으로 보낸다.
- 주어진 우선순위에 프로세스가 하나밖에 없다면 RR은 FIFO 와 동일하다.
- RR 또한 같은 우선순위의 프로세스들 중에서 스케줄링을 계속 하기 때문에 FIFO와 거의 유사함.
Normal 전략
SCHED_OTHER
은 기복적인 스케줄링 전략을 대표한다. (default non-real-time class)- 모든 normal-classed 프로세스는 고정된 우선순위 값으로 0을 가지고 있다.
- 결과적으로 동작중인 FIFO or RR 프로세스들은 normal 프로세스를 점유할 것이다.
- 이 스케줄러는 nice 값을 사용함.
Batch 스케줄링 전략
SCHED_BATCH
는 Batch or idle 스케줄링 전략이다.- real-time과 어느정도는 반대된다.
- 다른 프로세스들이 타임슬라이스를 다 썼더라도, 시스템에 동작 가능한 프로세스가 있다면 실행하지 않는다.
Linux 스케줄링 전략 설정하기
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <sched.h>
struct sched_param {
/* ... */
int sched_priority;
/* ... */
};
int sched_getscheduler (pid_t pid);
int sched_setscheduler (pid_t pid,
int policy,
const struct sched_param *sp);
sched_getscheduler()
와sched_setscheduler()
를 사용해서 리눅스 스케줄링 값을 조작할 수 있다.sched_getscheduler()
호출이 성공하면 pid 프로세스의 스케줄링 전략을 리턴한다.- pid가 0이면 호출을 실행한 프로세스의 스케줄링 정책이 반환됨.
- 예시
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
int policy; /* get our scheduling policy */ policy = sched_getscheduler (0); switch (policy) { case SCHED_OTHER: printf ("Policy is normal\n"); break; case SCHED_RR: printf ("Policy is round-robin\n"); break; case SCHED_FIFO: printf ("Policy is first-in, first-out\n"); break; case -1: perror ("sched_getscheduler"); break; default: fprintf (stderr, "Unknown policy!\n"); }
sched_setscheduler()
를 호출하면 pid 에다가 policy를 넣어준다.sp
- 정책과 관련된 다른 파라미터들을 넣어주는 곳
shced_param
- 구조 안의 유효한 값들은 policy에 따라 다름.
- SCHED_RR과 SCHED_FIFO 는 sched_priority가 필요하고 SCHED_OTHER는 필요없음.
- 예시
- 이 예시는 RR 정책으로 static priority를 1로 수정한다. ```c struct sched_param sp = { .sched_priority = 1 }; int ret;
ret = sched_setscheduler (0, SCHED_RR, &sp); if (ret == −1) { perror (“sched_setscheduler”); return 1; } ```
- 스케줄링 정책을 지정할 때 SCHED_OTHER를 제외하고는
CAP_SYS_NICE
설정이 필요하다.
6.6.5 스케줄링 파라미터 설정하기
- POSIX는 스케줄링 정책과 관련된 파라미터들을 설정하고 가져올 수 있게 하기 위해서
sched_getparam()
과sched_setparam()
을 지원한다.
1
2
3
4
5
6
7
8
9
10
11
#include <sched.h>
struct sched_param {
/* ... */
int sched_priority;
/* ... */
};
int sched_getparam (pid_t pid, struct sched_param *sp);
int sched_setparam (pid_t pid, const struct sched_param *sp);
sched_getscheduler()
호출은 오직 스케줄링 정책만 리턴하지만sched_getparam()
은 sp에다가 pid 프로세스와 연관된 스케줄링 파라미터들을 전달한다.- 예시
1 2 3 4 5 6 7 8 9 10
struct sched_param sp; int ret; ret = sched_getparam (0, &sp); if (ret == −1) { perror ("sched_getparam"); return 1; } printf ("Our priority is %d\n", sp.sched_priority);
- 만약 pid가 0이면 호출한 프로세스의 파라미터를 넘김.
sched_setscheduler()
또한 스케줄링 파라미터를 저장하긴 하지만,sched_setparam()
은 나중에 파라미터를 변경할 때 유용하다.- 예시
1 2 3 4 5 6 7 8 9
struct sched_param sp; int ret; sp.sched_priority = 1; ret = sched_setparam (0, &sp); if (ret == −1) { perror ("sched_setparam"); return 1; }
유효한 우선순위 값 범위 결정하기
- 리눅스에서는 1-99 값의 범위로 RT 스케줄링 정책을 지원한다.
- 리눅스는 현재 유효한 우선순위 값을 알기 위해서 시스템 콜을 지원한다.
1
2
3
4
5
#include <sched.h>
int sched_get_priority_min (int policy);
int sched_get_priority_max (int policy);
- 각각 유효한 우선순위 값의 최소값과 최대값을 리턴함.
policy
- 스케줄링 정책을 넣어줌
- 예시
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
int min, max; min = sched_get_priority_min (SCHED_RR); if (min == −1) { perror ("sched_get_priority_min"); return 1; } max = sched_get_priority_max (SCHED_RR); if (max == −1) { perror ("sched_get_priority_max"); return 1; } printf ("SCHED_RR priority range is %d - %d\n", min, max);
6.6.6 sched_rr_get_interval()
- SCHED_RR은 time slice를 사용한다는 것을 제외하고 SCHED_FIFO와 동일하게 작동한다.
- 만약 SCHED_RR 프로세스가 타임슬라이스를 다 썼다면, 스케줄러는 현재 우선순위의 동작 리스트 중 가장 마지막으로 간다.
- 이런 방법에서는 같은 우선순위의 모든 SCHED_RR 프로세스들은 Rount robin 으로 순회한다.
높은 우선순위의 프로세스들 (SCHED_FIFO of the same or higher priority) 은 SCHED_RR 프로세스의 타임슬라이스가 더 남았건 상관안하고 점유한다.
- POSIX 는 주어진 프로세스의 timeslice의 길이를 얻을 수 있는 인터페이스를 제공한다.
1
2
3
4
5
6
7
8
#include <sched.h>
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
int sched_rr_get_interval (pid_t pid, struct timespec *tp);
- 호출이 성공하면 timespec 구조의 tp에다가 pid에 할당된 타임슬라이스의 길이를 저장한다.
- POSIX에 따르면 이 함수는 SCHED_RR에만 사용할 수 있지만, 리눅스에서는 어떤 프로세스든 적용할 수 있다.
- 예시
1 2 3 4 5 6 7 8 9 10 11 12 13
struct timespec tp; int ret; /* get the current task's timeslice length */ ret = sched_rr_get_interval (0, &tp); if (ret == −1) { perror ("sched_rr_get_interval"); return 1; } /* convert the seconds and nanoseconds to milliseconds */ printf ("Our time quantum is %.2lf milliseconds\n", (tp.tv_sec * 1000.0f) + (tp.tv_nsec / 1000000.0f));
- 만약 프로세스가 FIFO 로 돌고있다면 tv_sec과 tv_nsec는 둘 다 0이다.
6.6.7 Real-time 프로세스의 주의점
6.6.8 Determinism (결정론)
- RT 프로세스는 결정론에 크게 좌지우지 한다.
- RT 컴퓨팅에서 행동은 결정론적인데, 만약 같은 인풋을 받았을 때 항상 같은 양의 시간에 같은 결과를 만들어야하기 때문.
- 최신 컴퓨터는 결정론적이지 않은데, 여러 계층에 걸친 캐시와 여러 개의 프로세스, 페이징, 스와핑, 그리고 멀티태스킹은 명령이 얼마나 걸릴지 예측할 수 없음
- 실시간 애플리케이션은 예측할 수 없는 부분과 최악의 지연을 제한하려고 시도한다.
선행 폴트 데이터와 메모리 락
- 종종 선행 폴트를 일으켜 스왑된 데이터를 메모리에 올린 다음, 주소 공간 내 모든 페이지를 실제 물리 메모리에 ‘락을 걸거나’, ‘고정 배선’한다.
- 메모리 락을 걸고 나면 커널은 절대로 이 페이지를 디스크로 스왑하지 않는다.
CPU 친화도와 실시간 프로세스
- 각 실시간 프로세스를 위해 프로세서 하나를 예약해두고 나머지 프로세스는 남은 프로세서상에서 시분할 방식으로 동작하게 한다.
- 구현 방법:
- init 프로그램을 수정 -
CPU_CLR (1, &set)
: CPU #1을 금지한다.- 실행 가능한 프로세서 집합은 부모 프로세스로부터 상속받게 된다.
- 실시간 프로세스가 CPU #1에서만 실행되도록 affinity를 준다. -
CPU_SET (1, %set)
- init 프로그램을 수정 -