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)(&param[0]),		// 쓰레드 함수의 전달 인자
		0,
		&dwThreadId[0]	// 쓰레드 ID 반환
	);
	hThread[1] = CreateThread(
		NULL,
		0,							// 스택의 크기 1MB로 설정
		ThreadProc,					// 쓰레드로 사용할 함수
		(LPVOID)(&param[2]),		// 쓰레드 함수의 전달 인자
		0,
		&dwThreadId[1]	// 쓰레드 ID 반환
	);
	hThread[2] = CreateThread(
		NULL,
		0,							// 스택의 크기 1MB로 설정
		ThreadProc,					// 쓰레드로 사용할 함수
		(LPVOID)(&param[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

+ Recent posts