728x90
쓰레드의 생성
- createThread 함수
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 핸들 상속 여부 결정
SIZE_T dwStackSize, // 독립 stack의 크기(기본 1MB)
LPTHREAD_START_ROUTINE lpStartAddress, // 쓰레드로 동작하기 위한 함수(쓰레드 main)
LPVOID lpParameter, // 쓰레드 함수에 전달할 인자
DWORD dwCreationFlags, // 생성 옵션
LPDWORD lpThreadId // 쓰레드 ID
);
- 생성 가능한 쓰레드의 갯수
-> OS가 지정할 수 있음
-> 보편적으로 허용할 수 있는 만큼 생성 가능
#include <stdio.h>
#include <Windows.h>
#include <tchar.h>
#define MAX_THREAD (1024*10)
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
DWORD threadNum = (DWORD)lpParam;
while (1)
{
_tprintf(_T("thread num : %d \n"), threadNum);
Sleep(5000);
}
return 0;
}
DWORD cntOfThread = 0;
int _tmain(int argc, TCHAR* argv[])
{
DWORD dwThreadId[MAX_THREAD];
HANDLE hThread[MAX_THREAD];
while (1)
{
hThread[cntOfThread] = CreateThread(
NULL,
0, // 스택의 크기 1MB로 설정
ThreadProc, // 쓰레드로 사용할 함수
(LPVOID)cntOfThread, // 쓰레드 함수의 전달 인자
0,
&dwThreadId[cntOfThread] // 쓰레드 ID 반환
);
if (hThread[cntOfThread] == NULL)
{
_tprintf(_T("MAXIMUM THREAD NUMBER: %d \n"), cntOfThread);
break;
} // 쓰레드를 생성하지 못하면 NULL이 반환
cntOfThread++;
}
for (DWORD i = 0; i < cntOfThread; i++)
{
CloseHandle(hThread[i]);
}
return 0;
}
쓰레드의 소멸
- return을 사용하는 경우
-> 쓰레드 main 함수(쓰레드 생성시 전달하는 함수)가 return 하면 종료가 됨
-> 이 경우가 안정적임
-> main 쓰레드에서 여러 함수에 일을 나눠주고 쓰레드가 return을 하면 종료 코드를 main 쓰레드에서 GetExitCodeThread로 얻을 수 있음
#include <stdio.h>
#include <Windows.h>
#include <tchar.h>
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
DWORD* nptr = (DWORD*)lpParam;
DWORD num1 = *nptr;
DWORD num2 = *(nptr + 1);
DWORD total = 0;
for (DWORD i = num1; i <= num2; i++)
{
total += i;
}
return total;
}
int _tmain(int argc, TCHAR* argv[])
{
DWORD dwThreadId[3];
HANDLE hThread[3];
DWORD param[] = { 1,3,4,7,8,10 };
DWORD total = 0;
DWORD result = 0;
hThread[0] = CreateThread(
NULL,
0, // 스택의 크기 1MB로 설정
ThreadProc, // 쓰레드로 사용할 함수
(LPVOID)(¶m[0]), // 쓰레드 함수의 전달 인자
0,
&dwThreadId[0] // 쓰레드 ID 반환
);
hThread[1] = CreateThread(
NULL,
0, // 스택의 크기 1MB로 설정
ThreadProc, // 쓰레드로 사용할 함수
(LPVOID)(¶m[2]), // 쓰레드 함수의 전달 인자
0,
&dwThreadId[1] // 쓰레드 ID 반환
);
hThread[2] = CreateThread(
NULL,
0, // 스택의 크기 1MB로 설정
ThreadProc, // 쓰레드로 사용할 함수
(LPVOID)(¶m[4]), // 쓰레드 함수의 전달 인자
0,
&dwThreadId[2] // 쓰레드 ID 반환
);
if (hThread[0] == NULL || hThread[1] == NULL || hThread[2] == NULL)
{
_tprintf(_T("Thread create error\n"));
return -1;
} // 쓰레드를 생성하지 못하면 NULL이 반환
WaitForMultipleObjects(3, hThread, TRUE, INFINITE); // 쓰레드가 종료될 때까지 대기
GetExitCodeThread(hThread[0], &result);
total += result;
GetExitCodeThread(hThread[1], &result);
total += result;
GetExitCodeThread(hThread[2], &result);
total += result;
_tprintf(_T("total (1~10) : %d\n"), total);
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
CloseHandle(hThread[2]);
return 0;
}
- ExitThread 함수 호출을 사용하는 경우
-> 쓰레드 내의 어떤 함수에서든 ExitThread를 하면 쓰레드가 종료가 됨
- TerminateThread 함수 호출을 사용하는 경우
-> 프로세스가 생성된 핸들로 쓰레드를 종료시키는 함수
728x90
'Programming > System Programming' 카테고리의 다른 글
윈도우즈 시스템 프로그래밍 - 12. 쓰레드의 생성과 소멸(3) (0) | 2020.07.26 |
---|---|
윈도우즈 시스템 프로그래밍 - 12. 쓰레드의 생성과 소멸(2) (0) | 2020.07.26 |
윈도우즈 시스템 프로그래밍 - 11. 쓰레드의 이해(5) (0) | 2020.07.23 |
윈도우즈 시스템 프로그래밍 - 11. 쓰레드의 이해(4) (0) | 2020.07.23 |
윈도우즈 시스템 프로그래밍 - 11. 쓰레드의 이해(3) (0) | 2020.07.22 |