05. 프로세스 스케줄러 2
(실습과 그림으로 배우는 리눅스 구조)
컨텍스트 스위치
논리 CPU 상에서 동작하는 프로세스가 다른 프로세스로 바뀌는 것을 말함
기본적으로는 타임 슬라이스를 다 소비했을 경우 발생
따라서 코드상에서 두 번의 함수콜이 있다고 가정할 때,
두 함수 사이에 프로세스가 멈추고 다른 프로세스가 실행 될 수도 있는 일
컨텍스트 스위치의 가능성을 항상 염두해 두자.
명령어를 통해 프로세스 개수를 셀 수 있음
프로세스의 상태
- 실행, 실행 대기 ; CPU 할당 대기
- 슬립 ; 이벤트 발생 대기
- ex) 키보드 입력, 디스크 읽기/쓰기, 네트워크 데이터 송수신 대기
- 파일 리드 요청 이후 프로세스는 슬립 상태로 빠졌다가, 읽기 완료시 실행 혹은 대기
- 유저 입력 대기 시 슬립 상태, 유저 입력시 실행 혹은 대기
- 좀비 ; 종료된 뒤 부모 프로세스가 종료 상태를 인식할 때까지 대기
- etc.
이러한 프로세스의 상태는 ps ax 명령어의 세 번째 필드 STAT을 통해 알 수 있다
- R ; 실행 or 실행 대기
- S or D ; 슬립
- 시그널에 따라 실행 상태로 되돌아 오는 것이 전자, 그렇지 않은 것이 후자(저장 장치 접근 대기???)
- 일반적으로 D는 수 ms 초 이후에 다른 상태로 바뀌며, 지나치게 오래 지속될 경우 disk I/O가 종료되지 않은 상태로 있거나, 커널 내의 문제를 의심해 봐야한다.
- bash가 슬립상태 인 것은 사용자로부터 입력을 기다리고 있기 때문
- ps ax는 실행 상태
- Z ; 좀비
프로세스의 상태 변환
그림에서 볼 수 있는 것 처럼
프로세스는 생성되는 시점부터 종료되는 시점까지 실행/실행가능/슬립 상태를 수시로 오간다.
idle 상태
- 특정 논리 CPU에서 아무 프로세스도 돌지 않을 때, CPU의 상태를 의미
- 실제로 CPU에서는 아이들(idle) 프로세스가 동작하고 있다.
- CPU의 특수 명령어를 통해서 논리 CPU를 휴식 상태로 만들어 하나 이상의 프로세스가 실행 가능한 상태가 될 때 까지 소비 전력을 낮추어 대기 상태로 있는다.
- sar 명령어를 통해 시간당 논리 CPU가 얼마나 idle 상태가 되는지 볼 수 있음 (1초마다 체크)
무한 루프를 도는 파이썬 프로그램을 데몬으로 돌린뒤 측정해보자.
%user 이 100%로 바뀌는 것을 확인할 수 있다.
유저로부터 입력을 받고 (첫 번째 슬립)
입력에 해당하는 파일을 읽는 (두 번째 슬립)
프로세스 0이 있다고 가정하고 아래 그림을 살펴보자.
논리 CPU로 한 번에 한 개의 프로세스만 실행시킬 수 있으며,
슬립 상태에서는 CPU 시간을 사용하지 않는다.
쓰루풋(throughput)
- 단위 시간당 처리량
- 완료한 프로세스의 수 / 경과시간
레이턴시(latency)
- 각 처리의 시작 ~ 종료까지 경과시간
- 처리 종료 시간 - 처리 시작 시간
CPU에 idle 상태가 자주 있는 경우엔, 프로세스를 더 띄움으로써 쓰루풋을 증가시킬 수 있다.
CPU 시간을 타임 슬라이스로 잘게 쪼개어 번갈아가면서 쓰다보니 CPU가 idle한 시간을 줄일 수 있기 때문이다.
이전 포스팅에 나온 예제에선 레이턴시가 프로세스 개수에 따라 리니어하게 증가하는 양상을 보였는데,
이유는 논리 CPU가 idle 상태가 거의 되지 않는 상황이었기 때문이다. 이러한 경우엔 쓰루풋은 변하지 않는다.
오히려 %idle이 0일 때 프로세스 개수가 증가하면 컨텍스트 스위치가 오버헤드가 될 수 있다.
정리하면, 이상적인 상황에서,
idle 상태가 없고, 실행 대기 상태의 프로세스가 없을 때 쓰루풋 및 레이턴시가 최대화된다.
- 서로 번갈아 쓰면 레이턴시가 길어지니깐!
어쨌든 이러한 수치들을 살피면서 시스템을 튜닝 할 때
앞서 살펴본 것 처럼, sar 명령어를 활용해서 지표들을 살피자
추가로,
-q 옵션을 주면 runq-sz 필드에 몇 개의 실행/실행대기 프로세스가 있는지 확인할 수 있음
논리 CPU가 여러 개일 때는
스케쥴러 안에 로드밸런서 및 글로벌 스케쥴러라는 기능이 동작.
- 여러 개의 논리 CPU에 프로세스를 공평하게 분배 (로드밸런서)
정리
- 1개의 CPU에서 동시에 처리되는 프로세스는 1개
- 여러 개의 프로세스가 실행 가능할 경우 각 프로세스를 적절한 타임 슬라이스마다 CPU에서 순차적으로 처리
- 멀티코어 CPU 환경에서는 여러 개의 프로세스를 동시에 동작 시킴으로써 쓰루풋을 올릴 수
- 당연히, 코어 개수 이상의 프로세스를 할당하면 쓰루풋은 오르지 않음
time 명령어를 통해서
- 경과 시간 ; real
- (실제) 사용 시간 ; user(사용자 모드), sys(커널 모드; 시스템 콜 실행 시간)
두 개를 측정 가능함
* 멀티코어에서 병렬로 실행 가능성을 염두 (user가 real의 2배라면 2개의 코어에서 실행됐을 가능성)
ps -eo 명령어!!
- 경과 시간 (elapsed)
- 사용 시간 (time)
의 측정이 가능
우선순위 변경!
- 스케쥴러에 관련된 시스템 콜 nice() ; 특정 프로세스에게 우선순위 부여
- (-19 부터 20까지) 세팅 가능하며, 기본값은 0
- 우선순위가 높을 수록 평균보다 더 많은 cpu 시간 배정














