CPU 스케줄링 또는 스레드 스케줄링
윈도우 운영체제가 각 스레드에 CPU 할당 시간을 적절하기 분배하기 위한 정책
윈도우 운영체제의 스케줄링 기법
우선 순위 Priority에 기반함
우선 순위가 높은 스레드에 먼저 CPU 시간을 할당해줌
스레드 우선순위를 결정하는 요소
프로세스 우선순위를 우선순위 클래스, 스레드 우선순위를 우선순위 레벨이라 함
우선순위 클래스
프로세스의 속성
한 프로세스가 생선한 스레드는 우선순위 클래스가 동일
윈도우 운영체제가 제공하는
(1) 우선순위 클래스
REALTIME_PRIORITY_CLASS (실시간)
HIGH_PRIORITY_CLASS (높음)
ABOVE_NORMAL_PRIORITY_CLASS (높은 우선순위)
NORMAL_PRIORITY_CLASS (보통)
BELOW_NORMAL_PRIORITY_CLASS (낮은 우선순위)
IDLE_PRIORITY_CLASS (낮음)
(2) 우선순위 레벨
THREAD_PRIORITY_TIME_CRITICAL
THREAD_PRIORITY_HIGHST
THREAD_PRIORITY_ABOVE_NORMAL
THREAD_PRIORITY_NORMAL
THREAD_PRIORITY_BELOW_NORMAL
THREAD_PRIORITY_LOWEST
THREAD_PRIORITY_IDLE
스레드는 우선순위 클래스 & 우선순위 레벨로 스레드간의 우선순위를 나타낸다.
https://learn.microsoft.com/ko-kr/windows/win32/procthread/scheduling-priorities
예약 우선 순위 - Win32 apps
스레드는 예약 우선 순위에 따라 실행되도록 예약됩니다.
learn.microsoft.com
윈도우의 스레드 스케줄링 방식
우선순위가 가장 높은 스레드에 CPU 시간을 할당해줌, 우선순위가 같은 스레드는 CPU 시간을 번갈아가면서 할당해줌
우선순위가 높은 스레드가 계속 CPU 시간을 요구하여 상대적으로 우선순위가 낮은 스레드는 CPU 시간을 전혀 할당받지 못하는 기아(starvation)라는 문제가 생긴다.
-> 윈도우 운영체제는 기아를 해결하기 위하여 오랜 시간 CPU 시간을 할당받지 못한 스레드의 우선순위를 단계적으로 끌어올려서 한번은 실행시킨다.
우선순위 레벨 관련 API 함수
(1) SetThreadPriority()
우선순위 레벨을 변경(설정)할 때 사용
[in] hThreadBOOL SetThreadPriority( [in] HANDLE hThread, [in] int nPriority ); // 성공 0이 아닌 값 // 실패 0
우선 순위 값을 설정할 스레드에 대한 핸들
[in] nPrioirty
스레드의 우선 순위 값
(2) GetThreadPriority()
현재 우선순위 레벨을 얻을 때 사용
int GetThreadPriority( [in] HANDLE hThread );
[in] hThread
스레드에 대한 핸들
6-2 스레드 우선순위 변경하기 실습
#include <windows.h>
#include <stdio.h>
DWORD WINAPI MyThread(LPVOID arg)
{
while (1);
return 0;
}
int main(int argc, char* argv[])
{
// 우선순위 값의 범위를 알려준다.
printf("priority: %d ~ %d\n", THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL);
// CPU 개수
SYSTEM_INFO si;
GetSystemInfo(&si);
int num = (int)si.dwNumberOfProcessors;
printf("number of CPUs = %d\n", num);
// CPU 개수만큼 스레드를 생성
for (int i = 0; i < num; i++)
{
HANDLE hThread = CreateThread(NULL, 0, MyThread, NULL, 0, NULL);
SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL);
CloseHandle(hThread);
}
// 우선순위를 낮게 설정
HANDLE hPriority = GetCurrentThread();
SetThreadPriority(hPriority, THREAD_PRIORITY_BELOW_NORMAL);
Sleep(1000);
printf("executing the main thread (%d)\n", GetThreadPriority(hPriority));
return 0;
}
스레드 API 함수
WaitForSingleObject()
특정 스레드가 종료할 때까지 기다리기
DWORD WaitForSingleObject( [in] HANDLE hHandle, [in] DWORD dwMilliseconds ); // 성공 : WAIT_OBJECT_0 dwMilliseconds 안에 성공 후 종료되는 경우 리턴값 // WAIT_TIMEOUT 시간 경과해서 끝난 경우 리턴값 // 실패 : WAIT_FAILED
[in] hHnadle
기다리게할 개체 핸들
[in] dwMilliseconds
제한 시간 간격(밀리초 단위), 0이 아닌 값을 지정하면 개체가 일정 시간동안 기다리게함
0이면 함수가 대기상태로 들어가지 않음, 즉시 반환
INFINITE이면 개체가 신호를 받을 때만 함수가 반환
*기다리게 할 수 있는 개체들
알림 변경, 큰솔 입력, 이벤트, 메모리 리소스 알림, Mutex, 프로세스, 세마포, 스레드, 대기 가능한 타이머
WaitForMultipleObjects()
지정된 개체 중 하나 또는 전부를 기다리게 하는 함수DWORD WaitForMultipleObjects( [in] DWORD nCount, [in] const HANDLE *lpHandles, [in] BOOL bWaitAll, [in] DWORD dwMilliseconds );
사용 예)
// 스레드 하나의 종료를 기다림 HANDLE hThread[2]; hThread[0] = CreateThread(...); hThread[1] = CreateThread(...); DWORD retval = WaitForMultipleObjects(2, hThread, FALSE, INFINITE); switch(retval) { case WAIT_OBJECT_0: // hThread[0] 종료 ... break; case WAIT_OBJECT_0 + 1: // hThread[1] 종료 ... break; case WAIT_FAILED: // 오류 발생 ... break; }
SuspendThread()
실행 일시 중지 함수DWORD SuspendThread( [in] HANDLE hThread //스레드 핸들 ); // 성공 : 중지 횟수 // 실패 : -1
ResumeThread()
일시 중지한 스레드 resume 하는 함수DWORD ResumeThread( [in] HANDLE hThread ); // 성공 : 중지 횟수 // 실패 : -1
Sleep()void Sleep( DWORD dwMilliseconds // 밀리초 );
6-3 스레드 실행 제어와 종료 wait 실습
#include <windows.h>
#include <stdio.h>
int sum = 0;
DWORD WINAPI MyThread(LPVOID arg)
{
int num = (int)(long long)arg;
for (int i = 1; i <= num; i++)
sum += i;
return 0;
}
int main(int argc, char* argv[])
{
int num = 100;
HANDLE hThread = CreateThread(NULL, 0, MyThread, (LPVOID)(long long)num, CREATE_SUSPENDED, NULL);
// CREATE_SUSPENDED : 스레드는 일시 중단된 상태로 만들어지고
// ResumeThread 함수가 호출될 때까지 실행되지 않습니다.
// 0 : 스레드는 만든 직후에 실행됩니다.
printf("스레드 실행 전. 계산 결과 = %d\n", sum);
ResumeThread(hThread);
WaitForSingleObject(hThread, INFINITE);
printf("스레드 실행 후. 계산 결과 = %d\n", sum);
CloseHandle(hThread);
return 0;
}
'코딩 > Network' 카테고리의 다른 글
[네트워크] UDP 서버-클라이언트 (0) | 2023.06.05 |
---|---|
[네트워크] 멀티스레드 TCP서버/스레드 동기화/임계영역/이벤트 (0) | 2023.06.05 |
[네트워크] 멀티스레드 (0) | 2023.04.15 |
[네트워크] 데이터 전송, 고정 길이, 가변 길이 (0) | 2023.04.15 |
[네트워크] TCP 서버-클라이언트 분석 (0) | 2023.04.15 |