스레드 생성 API
CreateThread() 함수
- 스레드 생성 후 스레드 핸들을 리턴
- OS의 스레드 관련 데이터 구조체를 간접적으로 참조하는 매개체 역할을 한다
#include <windows.h>
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 스레드 보안 특성 -> 보안을 위해 디폴트 NULL
SIZE_T dwStackSize, // 스레드에 할당되는 스택 크기
LPTHREAD_START_ROUTINE lpStartAddress, // 스레드 함수 호출
LPVOID lpParameter, // 스레드 함수에 전달할 매개변수(인자)
DWORD dwCreationFlags, // 스레드 제어하는 플래그
LPDWORD lpThreadId // 스레드의 ID 값
);
- lpThreadAttributes : 보안 디스크립터 정보를 전달한다!! -> 보안을 위해 NULL 포인터를 전달한다
- dwStackSize : 스레드에 할당되는 스택 크기!!
- lpStartAddress : 스레드 함수 호출
- lpParameter : 스레드의 함수에 전달할 매개변수 지정
- 포인터 크기보다 작거나 같은 데이터는 값 또는 주소형태로 전달한다
- 포인터 크기보다 큰 데이터는 값을 구조체나 배열에 넣고 주소 형태로 전달한다
// ====== lpParameter전달 ======
DWORD WINAPI ThreadProc(LPVOID lpParameter){}
// ===== 크기에 따라 전달 방법 =====
int value = 값;
// 포인터와 크기가 같거나 작을 경우
CreateThread(..., (LPVOID)value)... // 값의 형태로 전달
CreateThread(..., &(value))... // 주소를 전달한다
// 포인터보다 큰 데이터 전달
struct Mydata data ={};
CreateThread(..., &data) // 주소를 구조체로 전달
- dwCreationFlags : 새로운 쓰레드 생성 이후에 바로 실행 가능한 상태, 대기 상태를 결정
- 0 : 스레드 생성 후 바로 실행
- CREATE_SUSPENDED : 스레드가 생성되지만 대기상태(ResumeThread()함수를 호출하기 전까지 대기)
- lpThreadId : DWORD형 변수를 전달하면 스레드 ID가 저장된다
스레드 생성과 종료
- 스레드의 최대 개수[32bit 윈도우]
- 스레드 종료 방법
- 스레드 함수가 리턴한다
- 스레드 함수 내에서 ExitThread() 함수를 호출한다
- 다른 스레드가 TerminateThread() 함수를 호출한다
- 주 스레드가 종료하면 모든 스레드가 종료된다
- 스레드 종료 함수
#include <windows.h>
void ExitThread(
DWORD dwExitCode; // 종료 코드
);
#include <winodws.h>
BOOL ThermianteThread(
HANDLE hThread, // 종료할 스레드를 가리키는 핸들
DWORD dwExitCdoe // 종료 코드
);
// 성공 : 0이 아닌 다른 값
// 실패 : 0
- 스레드 함수 사용
DWORD WINAPI f(arg..){
return 0; // 스레드 종료
}
int main (){
// 스레드1 생성!
HANDLE hThread1 = CreateThread(NULL, 0, f, NULL, 0, NULL);
if(hThread1 == NULL) {오류 처리}
// 스레드2 생성
HANDLE hThread2 = CreateThread(NULL, 0, f, NULL, 0, NULL);
if(hThread2 == NULL) {오류 처리}
}
스레드 생성과 종료, 인자 전달하는 연습!!
// 스레드에 사용될 매개변수 구조체
struct Point3D {
int x, y, z;
};
- 1초(1000밀리초)마다 멈췄다가 구조체 형변환하고 스레드 ID를 생성한다
- DWORD WINAPI GetCurrentThreadId(void)를 통해 스레드의 식별 번호를 가져온다!!
- 스레드의 정보를 출력하고 스레드 함수를 리턴한다
//스레드 함수 정의
DWORD WINAPI MyThread(LPVOID arg) {
Sleep(1000); // 일시 정지 -> 1000 밀리초
Point3D* pt = (Point3D*)arg;
// 출력
printf("Running MyThread() %d : %d, %d, %d\n", GetCurrentThreadId(), pt->x, pt->y, pt->z);
return 0;
}
메인 함수에서 스레드를 생성하고 종료를 한다
CreateThread()함수 : 스레드를 생성한다
CreateThread(보안, 스택 크기, 함수 호출, 주소 매개변수, 즉시실행, 스레드 ID );
CloseHandle() : 스레드 함수를 종료한다
int main() {
// 첫 번째 스레드 생성!
Point3D pt1 = { 10,20,30 };
HANDLE hThread1 = CreateThread(NULL, 0, MyThread ,&pt1, 0, NULL);
// 보안, 크기, 스레드 함수 호출, 매개변수(주소), 0(즉시 실행), ID
if (hThread1 == NULL) return 1;
CloseHandle(hThread1);
// 두 번째 스레드 생성
Point3D pt2 = { 90, 40, 60 };
HANDLE hThread2 = CreateThread(NULL, 0, MyThread, &pt2, 0, NULL);
if (hThread2 == NULL) return 1;
CloseHandle(hThread2);
// 세 번째 스레드 생성
Point3D pt3 = { 50, 70, 80 };
HANDLE hThread3 = CreateThread(NULL, 0, MyThread, &pt3, 0, NULL);
CloseHandle(hThread3);
printf("Running main() %d\n", GetCurrentThreadId());
Sleep(2000);
return 0;
}
전체 코드
#include "Common.h"
struct Point3D {
int x, y, z;
};
//스레드 함수 (공통으로 사용되는 작업) 정의
DWORD WINAPI MyThread(LPVOID arg) {
Sleep(1000); // 일시 정지 -> 1000 밀리초
Point3D* pt = (Point3D*)arg;
// 출력
printf("Running MyThread() %d : %d, %d, %d\n", GetCurrentThreadId(), pt->x, pt->y, pt->z);
return 0;
}
int main() {
// 첫 번째 스레드 생성!
Point3D pt1 = { 10,20,30 };
HANDLE hThread1 = CreateThread(NULL, 0, MyThread ,&pt1, 0, NULL);
// 보안, 크기, 스레드 함수 호출, 매개변수(주소), 0(즉시 실행), ID
if (hThread1 == NULL) return 1;
CloseHandle(hThread1);
// 두 번째 스레드 생성
Point3D pt2 = { 90, 40, 60 };
HANDLE hThread2 = CreateThread(NULL, 0, MyThread, &pt2, 0, NULL);
if (hThread2 == NULL) return 1;
CloseHandle(hThread2);
// 세 번째 스레드 생성
Point3D pt3 = { 50, 70, 80 };
HANDLE hThread3 = CreateThread(NULL, 0, MyThread, &pt3, 0, NULL);
CloseHandle(hThread3);
printf("Running main() %d\n", GetCurrentThreadId());
Sleep(2000);
return 0;
}
이 프로그램을 실행 시키면 스레드가 실행되는 순서가 랜덤이라는 것을 알 수 있다
우리가 원하는 순서로 스레드를 실행 시키려면 스레드를 제어해야한다!!
스레드 제어(간단히)
- 스레드는 윈도우 운영체제의 실행 단위므로, 우선 순위를 변경하거나 실행을 중지하고 재시작하는 등의 제어기능을 윈도우 API에서 지원해준다
- 스레드 우선 순위 변경
- 각 스레드에 CPU 시간을 적절히 분배하기 위한 정책!!
- 스레드 스케줄링 OR CPU스케줄링 --> 우선 순위가 높은 것을 우선적으로 할당한다!
- 스레드 우선 순위를 결정하는 요소
- 프로세스 우선 순위 (우선 순위 클래스) : 프로세스 속성으로, 같은 프로세스가 생성한 스레드는 우선순위 클래스가 모두 같다!!!
- 스레드 우선 순위 (우선 순위 레벨) : 스레드 속성으로, 같은 프로세스에 속한 스레드 간 상대적인 우선 순위를 결정할 때 사용한다
'개인 공부 > 네트워크' 카테고리의 다른 글
네트워크P-011(멀티 스레드 TCP 서버 & 임계영역) (0) | 2023.04.24 |
---|---|
네트워크P-010(스레드 기다리기 & 재실행) (0) | 2023.04.21 |
네트워크P-008(스레드 & [이전 실습] 파일 전송) (1) | 2023.04.16 |
네트워크P-008 (두 데이터 합 & 1:1 간단한 TCP 채팅 ) (0) | 2023.04.15 |
네트워크P-007 (데이터 전송 실습) (1) | 2023.04.15 |