◎ 우선 순위
스레드 우선순위는 최저 0부터 최고 31까지의 숫자로 우선순위가 할당된다.
◎ CPU 시간 할당
우선순위 31스레드를 검사하고 라운드 로빈 방식으로 스레드스케쥴한다. 우선순위31 스레드가 스케쥴 될수 있는한 0~30까지의 어떤 스레드에게도 CPU를 할당하지않는다. 이런 상태를 기아현상(Starvation) 이라 부른다.
그렇다면 낮은 순위 스레드는 대체 왜 만드는것일까? CPU는 항상 바쁘게 일을 하려고 한다. 낮은우선순위 스레드가 동작을 한다는건 해당 CPU가 할일이 없어서 낮은 우선 순위에게까지 할당이 됐다는 얘기이며, 이 말은즉 평소에는 작동을 하지 않다가 CPU가 할일이 없어지면 그때 동작하는 스레드란 의미로 받아들이면 되겠다. 무슨 프로그램이 있을까? 알아서 생각해보자.
※ OS가 부팅이 될때 시스템은 제로 페이지 스레드(Zero page thread)라 불리는 특별한 스레드를 생성한다. 이 스레드의 우선순위는 0 이며 전체 시스템에서 유일하게 우선순위0을 가지는 스레드이다. 제로페이지 스레드는 다른 모든 스레드가 수행을 하지 않을때 시스템에서 램의 모든 자유 페이지를 0으로 초기화 하는 일을 한다.
◎ Windows Application Thread 의 우선순위 지원
윈도우는 6개의 우선순위 클래스를 제공한다. 유후(Idle), 보통미만(Low normal), 보통(normal), 보통 초과(above normal), 높음(high), 실시간(real time)이다. 일반적으로 애플리케이션의 99%가 보통(normal)이다.
우선순위 클래스
| 우선순위 클래스 | 설명 |
| 실시간(Real Time) | 이 프로세스 내의 스레드는 임계 시간 작업을 실행하기 위하여 이벤트에 즉시 응답한다. 이 프로세스의 스레드는 또한 운영체제 컴포넌트를 선점한다. 이 우선순위 클래스는 극단적인 주의가 필요할때 사용한다. |
| 높음(High) | 이 프로세스 내의 스레드는 임계 시간 작업을 실행하기 위하여 이벤트에 즉시 응답한다. 작업 관리자는 이클래스에서 실행된다. 그래서 사용자는 응답이 없는 프로세스를 죽일 수 있다. |
| 보통 초과(above normal) | 이 프로세스 내의 스레드는 보통과 높은 우선순위 클래스 사이에게 실행된다.(Windows 2000에서 새로생김) |
| 보통(normal) | 이 프로세스 내의 스레드는 특별한 스케쥴링 도움이 필요없다. |
| 보통 미만(Below normal) | 이 프로세스 내의 스레드는 보통과 유휴 우선순위 클래스 사이에서 실행된다.(Windows 2000에서 새로생김) |
| 유휴(Idle) | 이 프로세스 내의 스레드는 시스템이 다른 유휴 상태일 때 실행된다. 이 프로세스는 보통 화면 보호기 또는 백그라운드 유틸리티와 통계랑을 모으는 소프트웨어에서 사용된다. |
상대 스레드 우선순위
| 상대스레드 우선순위 | 설명 |
| 시간 우선 | 31에서 실시간 우선순위 클래스가 실행되고, 15에서 다른 우선순위 클래스가 실행된다. |
| 아주높음 | 보통보다 두레벨 높은 스레드가 실행된다. |
| 보통초과 | 보통보다 한레벨 높은 스레드가 실행된다. |
| 보통초과 | 프로세스의 우선순위 클래스의 보통으로 스레드가 실행된다. |
| 보통미만 | 보통보다 한 레벨 낮은 스레드가 실행된다. |
| 아주낮음 | 보통보다 두 레벨 낮은 스레드가 실행된다. |
| 유휴 | 16에서 실시간 우선순위 클래스의 스레드가 실행되고, 1에서 다른 우선순위 클래스가 실행된다. |
위 두가지의 표를 가지고 스레드의 우선순위가 결정된다. 그 세부 내용은 아래와 같다.(windows2000 기준임)
| 유휴 | 보통보다 낮음 | 보통 | 보통보다 높음 | 높음 | 실시간 | |
| 시간 우선 | 15 | 15 | 15 | 15 | 15 | 31 |
| 아주 높음 | 6 | 8 | 10 | 12 | 15 | 26 |
| 보통 초과 | 5 | 7 | 9 | 11 | 14 | 25 |
| 보통 | 4 | 6 | 8 | 10 | 13 | 24 |
| 보통 미만 | 3 | 5 | 7 | 9 | 12 | 23 |
| 아주 낮음 | 2 | 4 | 6 | 8 | 11 | 22 |
| 유휴 | 1 | 1 | 1 | 1 | 1 | 16 |
※ 우선순위 0인 스레드는 사용자 애플리케이션에서는 절대 만들수없다.
※ 우선순위 레벨 17, 18, 19, 20, 21, 27, 28, 29, 30 은 일반적인 사용자 애플리케이션에서는 사용할 수 없다. 장치 드라이브를 써서 커널모드에서 실행한다면 이 레벨을 사용할수있다.
※ 실시간 우선순위 클래스의 스레드는 우선순위 레벨이 16 이하로 될 수 없다. 이와 비슷하게 실시간이 아닌 우선순위 클래스는 15 위로 될수가 없다.
◎ 프로세스의 우선순위 클래스 변경하기
프로세스의 우선순위 클래스를 할당하는 방법은 두가지가 있다.
1. CreateProcess 의 인자 fdwCreate 파라미터에 원하는 우선순위 클래스를 전달한다.
2. BOOL SetPriorityClass(HANDLE hProess, DWORD fdwPriority) 함수를 호출한다.
위의 DWORD fdwPriority에 들어가는 인자는 다음과 같다.
실시간 : REALTIME_PRIORITY_CLASS
높음 : HIGHT_PRIORITY_CLASS
보통초과: ABOVE_NORMAL_PRIORITY_CLASS
보통 : NORMAL_PRIORITY_CLASS
보통미만:BELOW_NORMAL_PRIORITY_CLASS
유휴 :IDLE_PRIORITY_CLASS
프로세스의 우선순위 클래스를 검색하는 함수는 다음과 같다.
DWORD GetPriorityClasss(HANDLE hProcess);
이 함수는 위 식별자 중 하나를 리턴한다.
◎ 스레드의 상대우선순위 설정하기
스레드의 상대 우선순위를 변경하는 함수는 다음과 같다.
BOOL SetThreadPriority(HANDLE hThread, INT nPriority)
nPriority 의 값은 다음과 같다.
시간우선 : THREAD_PRIORITY_TIME_CRITICAL
아주높음 :THREAD_PRIORITY_HIGHEST
보통초과 :THREAD_PRIORITY_ABOVE_NORMAL
보통 :THREAD_PRIORITY_NORMAL
보통미만 :THREAD_PRIORITY_BELOW_NORMAL
아주낮음 :THREAD_PRIORITY_LOWEST
유휴 :THREAD_PRIORITY_IDLE
현재 스레드의 상대 우선순위를 검색하는 함수는 다음과 같다.
int GetThreadPriority(HANDLE hThread);
이 함수는 위 테이블의 식별자중 하나를 리턴한다.
◎ 스레드 우선순위 레벨 자동 상승
1. 스레드의 우선순위 레벨은 스레드의 기본 우선순위 레벨 아래도 절대로 내려가지않는다.
2. 장치 드라이버는 스레드의 우선순위레벨을 임시로 올릴수 있다.
ex) 우선순위 13인 스레드에 키보드 메세지가 입력되었을시 키보드 장치 드라이버는 우선순위 13인 스레드의 우선순위를 15로 올린다.(실행후 다시 원래대로 돌아온다.)
3. 시스템은 기본 우선순위 레벨이 1에서 15인 스레드만 상승시킨다.
4. 스스템은 레벨이 15위인 실시간 범위의 스레드는 절대 상승시키지 않는다.
◎ 스레드의 우선순위 레벨을 막는 방법
위의 상황이 스레드 성능에 안좋은 영향을 미친다는 말이 있었다. 그래서 MS는 다음과 같은 함수를 추가했다.
BOOL SetProcessPriorityBoost(HANDLE hProcess, BOOL DisablePriorityBoost);
BOOL SetThreadPriorityBoost(HANDLE hThread, BOOL DiasblePriorityBoost);
SetProcessPriorityBoost : 프로세스내의 모든 스레드의 우선순위 상승을 가능 또는 불가능하게 설정한다.
SetThreadPriorityBoost : 개별 스레드의 우선순위 상승을 가능 또는 불가능하게 한다.
현재 스레드 혹은 프로세스의 스레드 우선순위 레벨 동적 상승 기능의 여부는 다음의 함수로 알수있다.
BOOL GetProcessPriorityBoost(HANDLE hProcess, PBOOL pDisablePriorityBoost);
BOOL GetThreadPriorityBoost(HANDLE hThread, PBOOL pDiasblePriorityBoost);
※ 윈도우98은 위 네가지의 함수를 지원하지 않는다.
※ 시스템이 동적 스레드우선순위를 상승 시킬경우 다음의 상황이 발생할 수 있다.
1. 우선순위 4인 스레드가 실행을 준비한다.
2. 우선순위 8인 스레드가 계속해서 스케쥴 가능하여 우선순위 4인 스레드가 실행되지 않는다.
3. 시스템은 해당 스레드가 스케쥴될수 있는데 실행되지 못한 상태가 3~4초간 지속이 되었을때 할당받지못한 스레드(우선순위4인 스레드)의 우선순위를 자동적으로 15로 상승시키며, 시간할당량은 두배로 변경이 된후 실행된다. 할당량을 다 사용하였을때 기본우선순위로 돌아온다.
