이 포스트는 널널한 개발자님의 강의를 듣고 작성한 글입니다.
컴퓨터 세상을 국가라고 했을 때 프로세스가 한 가정이고 그 가정 속에 한 개인이 스레드이다. OS는 일종의 프로그램(프로세스)로 백그라운드에서 실행이 된다. OS는 user-mode-application 영역의 process들을 support한다.
즉, 프로세스들은 스케줄링 한다는 것은 가장 중요한 것은 프로세스를 식당의 손님이라고 하면 이 프로세스 안의 스레드들이 CPU 자원을 소모한다. 스레드는 어떤 프로세스 안에 속해 있는데 이 프로세스를 또 하나의 그룹으로 묶일 수 있는데 그 그룹이 Job이다.
스케줄링이란 OS가 프로세스 줄 세우기를 하는 것인데 CPU의 핵심적인 전산자원을 스레드들이 선점하는 방식이다. 쉽게 말해 OS가 스레드들을 줄을 세워서 '너 이 만큼 가져가~'라고 하는 것이다.
스케줄링 단계에서는 크게 1~3단계로 나눠지는데 이제까지 우리가 애기했던 것들이 Lv3 저수준 스케줄링이다. 즉, 스레드들이 대기되면 OS가 '너 잠깐 비켜봐~'라고 하는 것들이 저수준 스케줄링이다.
Lv1 고수준 스케줄링은 다른 말로 장기 스케줄링 혹은 Job 스케줄링이라고 부르는데 이때 Job이 위에서 언급한 프로세스가 속한 그룹이다. 이 수준의 스케줄링은 전체적인 시스템의 부하상태를 고려한다. 즉, 시스템의 전체적인 부하상태 즉, 큰 틀에서의 현재 부하상태를 고려하고 CPU를 어떻게 나눠야 할지를 판단해야 한다.
쉽게 애기해보면 고수준 스케줄링이 식장의 전체 손님 수를 조절한다고 하면 저수준 스케줄링은 각 손님의 주문과 그에따른 요리제공 순서를 미세하고 조절하는 작업라고 볼 수 있다. 중간수준 스케줄링은 대기줄을 서는 손님을 관리하는 것이다.
결론적으로 고수준이든 저수준이든 중간수준이든간에 이런것들이 존재하는 이유는 기본적으로 시스템의 과부하 상태를 막는 것이다. 그려다보니 프로세스가 새로 생성된다고 해도 일단 대기상태에 있다가 20명의 정원 식당에서 20명까지는 활성화 프로세스가 되는 것이고 그 외 나머지는 보류 프로세스가 되는 것이다.
스케줄링의 목적
1. 공평성
2. 효율성
3. 안정성
4. 확장성
5. 반응 시간 보장
6. 무한 연기 방지
스케줄링에는 선점형 스케줄링이 있고 비선점형 스케줄링이 있다. 선점형은 이제까지 우리가 설명한 것인데 예를 들어 Excel이라는 프로그램과 word라는 프로그램이 작동중인데 Excel이 CPU를 쓰는 동안 word는 wait상태가 되고 OS가 Excel을 대상으로 suspend를 하면 Excel이 wait상태가 되고 word가 활성화 상태가 된다. 이것이 선점형 스케줄링이다. 즉, 어떤 프로세스가 CPU자원을 선점해서 쓰려고 하는데 그걸 OS가 통제할 수 있는 상황이면 선점형이다. 보통의 상황의 경우 선점형 방식을 채택한다.
비선점형 방식은 선점형 방식 정반대이다. 일단 일이 시작되면 이 일이 끝날 때까지 다른 일은 wait상태이다. 즉, 어떤 프로세스가 CPU를 점유하면 다른 프로세스가 이를 뺏을 수 없는 스케줄링 방식이다. 물론 OS는 강제로 뺏을 수 있긴 하다.
그래서 일반적인 경우 선점형이고 특이한 경우만 비선점형 방식을 채택한다.
스케줄링을 애기하면 우선순위 애기가 딸려나온다. Process + Thread별로 우선순위를 정할 수 있는데 이 우선순위는 아래와 같이 5단계로 나뉜다.
매우 낮음 < 약간 낮음 < 보통 < 약간 높음 < 매우 높음
일단 프로세스를 띄우면 보통단계로 시작을 하는데 미디어 플레이어와 같이 4K영상을 시청하는 경우 성능이 안 좋으면 영상이 뚝뚝 끊기고 플레이어가 맛이 갈 경우가 있는데 이런 경우는 약간 높음이나 매우 높음으로 우선순위를 높여줘야 하고 압축해제같은 백그라운드 작업은 우선순위를 매우 낮음 혹은 약간 낮음으로 설정해주면 효율적인 우선순위 방식이다.
즉, GUI를 가지는 전면부는 끊기거나 이상이 있으면 클라이언트들이 바로 컴플레인이 들어오지만 백그라운드 처리로직은 사용자들이 모르기 때문에 우선순위를 낮춰줘야 한다.
예를 들면 느린 I/O가 되면 특정 CPU를 선점해서 오랬동안 lock을 걸고 wait을 한다. 매우 낭비이다, 그러면 이런 처리는 비동기 처리를 해야하는거고 이래서 non-blocking I/O가 나오는 것이다. 이렇게 비동기처리를 하고 GUI부분이 살아있다고 표시를 해줘야 사용자들의 불편이 없을 것이다.
그런데 가끔 백그라운드 작업의 우선순위를 높여줘야 할 때가 있다. 그런 환경이 서버같은 경우가 그렇다.
스케줄링 우선순위에 대해서 전면 프로세스보다 더 높은 우선순위를 가지는게 있는데 그게 바로 커널 프로세스다. 그러면 여러분은 IOCP가 왜 빠른지 이해가 될 것이다. IOCP는 Kernel I/O를 하는 역할을 하기 때문이며 커널 프로세스가 가장 높기 때문에 빠른 것이다.