[System Programming] 12장 쓰레드의 생성과 소멸

Windows에서의 쓰레드 생성과 소멸

쓰레드의 생성

윈도우에서 사용할 수 있는 가장 기본적인 쓰레드 생성 함수는 CreateThread이다.

HANDLE CreateThread(
    LPSECURITY_ATTRIBUTES lpThreadAttributes, // 핸들의 상속여부
    SIZE_T dwStackSize, // 쓰레드의 스택 크기, 0은 디폴트를 의미
    LPTHREAD_START_ROUTINE lpStartAddress, // 쓰레드로 동작하기 위한 함수, 반환 타입은 DWORD, 매개변수는 LPVOID(void *)
    LPVOID lpParameter, // 쓰레드 함수에 전달할 인자를 지정하는 용도로 사용, main의 argv와 유사함
    DWORD dwCreationFlags, // 전달인자, CREATE_SUSPENDED가 전달되면 Blocked 상태에 놓이게 된다.
    LPTWORD lpThreadId // 쓰레드 ID를 전달받기 위한 변수의 주소값을 전달한다.  
); 

CountThread.cpp -

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <tchar.h>
#include <windows.h>

#define MAX_THREADS (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_THREADS];
	HANDLE hThread[MAX_THREADS];

	// 생성 가능한 최대 개수 쓰레드 생성
	while (1) {
		hThread[cntOfThread] =
			CreateThread(
				NULL,	// 디폴트 보안 속성 지정
				0,	// 디폴트 스택 사이즈
				ThreadProc,	// 쓰레드 함수
				(LPVOID)cntOfThread, // 쓰레드 함수의 전달 인자
				0,	// 디폴트 생성 flag 지정
				&dwThreadID[cntOfThread] // 쓰레드 id반환
			);


		// 쓰레드 생성 확인
		if (hThread[cntOfThread] == NULL) {
			_tprintf(
				_T("MAXIMUM THREAD NUMBER: %d \n"),
				cntOfThread
			);
			break;
		}
		cntOfThread++;
	}

	for (DWORD i = 0; i < cntOfThread; i++)
	{
		CloseHandle(hThread[i]);
	}
	return 0;
}
#include "stdio.h"
#include "tchar.h"
#include "windows.h"

static int total = 0;

DWORD WINAPI ThreadProc(LPVOID lpParam)
{
    DWORD * nPtr = (DWORD *) lpParam;

    DWORD numOne = *nPtr;
    DWORD numTwo = *(nPtr+1);

    for (DWORD i= numOne; i<=numTwo; i++)
    {
        total += i;
    }
    return 0; // 정상적 종료
}

int _tmain(int argc, TCHAR * argv[])
{
    DWORD dwThreadID[3];
    HANDLE hThread[3];

    DWORD paramThread[] = {1,3,4,7,8,10};

    hThread[0] =
            CreateThread(
                    NULL , 0 ,
                    ThreadProc ,
                    (LPVOID) (&paramThread[0]),
                    0 , &dwThreadID[0]
                    );
    hThread[1] =
            CreateThread(
                    NULL , 0 ,
                    ThreadProc ,
                    (LPVOID) (&paramThread[2]),
                    0 , &dwThreadID[1]
            );
    hThread[2] =
            CreateThread(
                    NULL , 0 ,
                    ThreadProc ,
                    (LPVOID) (&paramThread[4]),
                    0 , &dwThreadID[2]
            );

    if (hThread[0] == NULL || hThread[1] == NULL || hThread[2] == NULL)
    {
        _tprintf(_T("thread creation fault! \n"));
        return -1;
    }

    WaitForMultipleObjects(3,hThread,TRUE,INFINITE);

    _tprintf(_T("total (1~10) : %d \n"), total);

    CloseHandle(hThread[0]);
    CloseHandle(hThread[1]);
    CloseHandle(hThread[2]);
    return 0;
}

쓰레드의 소멸(쓰레드 생성에 대한 추가적인 이야기 포함) 쓰레드의 성격과 특성 힙,데이터 영역, 그리고 코드 영역의 공유에 대한 검증 동시접근에 있어서의 문제점 프로세스로부터의 쓰레드 분리 ANSI 표준 C 라이브러리와 쓰레드 쓰레드의 상태 컨트롤 쓰레드의 상태 변화 Suspend & Resume 쓰레드의 우선순위 컨트롤

출처

윤성우, ⌜뇌를 자극하는 윈도우즈 시스템 프로그래밍⌟, 한빛미디어, 2006
유튜브, "한빛미디어", "뇌를 자극하는 윈도우즈 시스템 프로그래밍", https://www.youtube.com/watch?v=GVX-m3RF-K0&list=PLVsNizTWUw7E2KrfnsyEjTqo-6uKiQoxc Github, "system_programming", https://github.com/connieya/system_programming