스레드 제어
- 스레드는 윈도우 운영체제의 실행 단위므로, 우선 순위를 변경하거나 실행을 중지하고 재시작하는 등의 제어기능을 윈도우 API에서 지원해준다
- 스레드 우선 순위 변경
- 각 스레드에 CPU 시간을 적절히 분배하기 위한 정책!!
- 스레드 스케줄링 OR CPU스케줄링 --> 우선 순위가 높은 것을 우선적으로 할당한다!
- 스레드 우선 순위를 결정하는 요소
- 프로세스 우선 순위 (우선 순위 클래스) : 프로세스 속성으로, 같은 프로세스가 생성한 스레드는 우선순위 클래스가 모두 같다!!!
- 스레드 우선 순위 (우선 순위 레벨) : 스레드 속성으로, 같은 프로세스에 속한 스레드 간 상대적인 우선 순위를 결정할 때 사용한다
- 우선 순위 클래스
REALTIME_PRIORITY_CLASS(실시간)
HIGH_PRIORITY_CLASS(높음)
ABOVE_NORMAL_PRIORITY_CLASS(높은 우선순위)
NORMAL_PRIORITY_CLASS(보통)
BELOW_NORMAL_PRIORITY_CLASS(낮은 우선순위)
IDLE_PRIORITY_CLASS(낮음)
- 우선 순위 레벨
THREAD_PRIORITY_TIME_CRITICAL
THREAD_PRIORITY_HIGHEST
THREAD_PRIORITY_ABOVE_NOLMAL
THREAD_PRIORITY_NORMAL
THREAD_PRIORITY_BELOW_NORMAL
THREAD_PRIORITY_LOWEST
THREAD_PRIORITY_IDLE
스레드 스케줄링 방식
- 우선 순위가 가장 높은 스레드에 CPU시간을 할당한다
- 우선 순위가 같은 스레드가 여러개 있을 때는 CPU시간을 번갈아 가며 할당한다
- 우선순위가 높은 스레드가 계속 CPU시간을 요구하면 우선순위가 낮은 스레드는 CPU시간을 전혀 할당 받지 못하는 기아 문제가 생긴다
- 기아 문제 해결
- OS는 기아 문제가온 스레드의 우선순위를 단계적으로 끌어 올려 우선순위가 낮은 CPU도 사용할 수 있게한다
우선순위 레벨 조작 함수
- 응용프로그램이 직접 우선 순위를 변경하기도 한다
SetThreadPrioity : 우선 순위 변경 함수
#include <windows.h>
BOOL SetThreadPriority(
HANDLE hThread, // 스레드 핸들
int nPrioriy // 우선 순위 레벨
);
// 성공 : 0이 아닌 값들
// 실패 : 0
GetThreadPriority : 우선 순위를 알고 싶을 때 사용하는 함수
#include <windows.h>
int GetThreadPriority(
HANDLE hThread // 스레드 핸들
);
// 성공 : 우선순위 레벨
// 실패 : THREAD_PRIORITY_ERROR_RETURN
스레드 종료 기다리기
- 스레드는 일단 생성되면 CPU 시간을 사용하려고 다른 스레드와 경쟁하면서 독립적으로 실행한다
WaitForSingleObject( ) 함수
- 특정 스레드가 종료될 때까지 기다린다 -> 1개의 스레드를 생성
#include<windows.h>
DWORD WaitForSIngleObject(
HANDLE hHandle, // 상대 스레드
DWORD dmMilliseconds // 대기 시간 밀리초
);
// 성공 : WAIT_OBJECT_0 또는 WAIT_TIMEOUT
// 실패 : WAIT_FAILED
- hHandle : 종료를 기다릴 대상 스레드
- dwMilliseconds : 대기 시간(밀리초) -> 대기 시간이 지나도 종료되지 않으면 WAIT_FAILED리턴이된다
- 대기시간으로 INFINITE값을 사용하면 스레드가 종료할때까지 기다린다
WaitForMultipleObject() 함수
- 둘 이상의 스레드가 종료될 때까지 기다린다
#include<windows.h>
DWORD WaitForMulitpleObjects(
DWORD nCount, const HANDLE *lpHandles, // 모든 스레드 핸들
BOOL bWaitAll, // 스레드들이 종료되었는지 확인
DWORD dmMilliseconds // 대기 시간 밀리초
);
// 성공 : WAIT_OBJECT_0 또는 WAIT_TIMEOUT
// 실패 : WAIT_FAILED
- nCount, lpHandles : 스레드 핸들을 배열에 넣어서 전달한다
- nCount : 배열 크기
- lpHandles : 배열의 시작 주소
- bWaitAll : 모든 스레드가 종료됐는지 체크 (TRUE : 모든 스레드 종료 / FALSE : 한스레드 종료하는 즉시 리턴)
스레드 실행 중지와 재실행
- 실행 중지 함수 : 스레드 핸들을 보유하고 있으면 해당 스레드 실행을 일시 정지
#include<windows.h>
DWORD SuspendThread(
HANDLE hThread // 스레드 핸들
);
// 성공 : 중지 횟수
// 실패 : -1
- 재실행 함수
#incldue <windows.h>
DWORD ResumeThread(
HANDLE hThread // 스레드 핸들
);
// 성공 : 중지 횟수
// 실패 : -1
- OS에서 스레드 중지 횟수를 관리한다
- SuspendThread()함수를 호출할 때마다 1씩 증가
- ResmeThread()함수를 호출할 때마다 1씩 감소
- 중지 횟수가 0보다 크면 스레드는 실행중지 상태이다
실행 중지 함수 Sleep()
void Sleep(
DOWRD dwMilliseconds // 밀리초
);
- Sleep()함수를 호출하면 밀리초로 지정한 시간이 지나면 자동으로 재시작한다
스레드 기다리기 재실행 실습
#include "Common.h"
int sum = 0;
DWORD WINAPI MyThread(LPVOID arg){
int num = (int)arg;
for (int i = 1; i <= num; i++)
sum += i;
return 0;
}
int main() {
int num = 100;
HANDLE hThread = CreateThread(NULL, 0, MyThread, (LPVOID)num, CREATE_SUSPENDED, NULL); // 스레드 생성
if (hThread == NULL) return 1;
printf("스레드 실행 전!\n계산 결과 = %d\n", sum);
ResumeThread(hThread); // 스레드 재실행!
WaitForSingleObject(hThread, INFINITE); // 스레드 종료 기다리기
printf("스레드 실행 후!\n계산 결과 = %d\n", sum);
CloseHandle(hThread);
return 0;
}
'개인 공부 > 네트워크' 카테고리의 다른 글
네트워크P-012(스레드 동기화 - 이벤트) (1) | 2023.05.07 |
---|---|
네트워크P-011(멀티 스레드 TCP 서버 & 임계영역) (0) | 2023.04.24 |
네트워크P-009 (스레드 생성 & 종료) (0) | 2023.04.20 |
네트워크P-008(스레드 & [이전 실습] 파일 전송) (1) | 2023.04.16 |
네트워크P-008 (두 데이터 합 & 1:1 간단한 TCP 채팅 ) (0) | 2023.04.15 |