SPRING :: NOTE

[C] WIN32 Thread / 1부터 100까지 더하는동안 점찍기 본문

Development Language/C · C++ · MFC

[C] WIN32 Thread / 1부터 100까지 더하는동안 점찍기

RAYZIE 2016. 6. 8. 18:19
반응형
#define _CRT_SECURE_NO_DEPRECATE
 
#include "windows.h"
 
typedef struct SumInfo
{
    int a, b, s;
}SUMINFO, *PSUMINFO;
 
DWORD WINAPI Sum(void* p);
HANDLE g_hConsoleOut;
 
void writeString(LPCTSTR lpszFormat, ...)
{
    char str[1024] = { 0 };
    va_list argList;
    DWORD dwNumberOfBytesWritten;
 
    va_start(argList, lpszFormat);
    wvsprintf(str, lpszFormat, argList);
    va_end(argList);
 
    WriteFile(g_hConsoleOut, str, lstrlen(str), &dwNumberOfBytesWritten, NULL);
}
 
void main()
{
    char temp[1024];
    DWORD dwThreadId, dwExitCode;
    //기본 콘솔 출력 버퍼 오브젝트 핸들을 얻는다.
    g_hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
    if (g_hConsoleOut == INVALID_HANDLE_VALUE)
    {
        return;
    }
 
    writeString(TEXT("*** 예제 [Thread] WIN32 API를 이용한 쓰레드 예제 ***\n"));
   
    // 기본 힙 메모리 오브젝트를 이용해서 메모리 할당
    PSUMINFO psi = (PSUMINFO)HeapAlloc(GetProcessHeap(), 0, sizeof(SUMINFO));
    psi->a = 1;
    psi->b = 100;
    psi->s = 0;
 
    HANDLE h = CreateThread(
        NULL, //보안속성 SECURITY_ATTRIBUTES 구조체 포인터
        0,  //스레드가 실행될 때 Commit 상태의 스택 크기 설정
        Sum,    //스레드 오브젝트가 실행할 함수 포인터
        psi,    // 스레드 함수에게 전달할 포인터. 일반적으로 데이터를 보냄
        NULL,   //스레드 함수 실행 옵션
        &dwThreadId);   //스레드 아이디를 리턴받는다
 
    if (h == NULL)
        return;
 
    // 스레드의 상태를 확인하여 종료될 때를 기다린다.
    while (GetExitCodeThread(h, &dwExitCode))
    {
        if (dwExitCode != STILL_ACTIVE)
        {
            CloseHandle(h);
            break;
        }
        else
        {
            //대기하고 있는 동안 화면에 "."를 찍는다.
            writeString(TEXT("."));
            Sleep(20);
        }
    }
    HeapFree(GetProcessHeap(), 0, psi);
}
 
DWORD WINAPI Sum(void* p)
{
    PSUMINFO psi = (PSUMINFO)p;
    do //psi->a부터 psi->b까지의 합을 psi->s에 대입한다.
    {
        psi->s += psi->a;
        Sleep(20);
    } while (psi->a++ != psi->b);
    writeString(TEXT("\nSum결과%d\n"), psi->s);
    return psi->s;
 
}


설명 : 



위 예제는 C 런타임 라이브러리 함수를 이용하지 않았다.

따라서 헤더파일은 windows.h 하나만 필요로 한다. CreateThread API함수를 사용하여 다중 스레드 프로그램을 작성할 경우에는 런타임 라이브러리 함수를 혼용하지 말아야 한다. 


예제 소스 코드에서 사용된 vwsprintf, WriteFile, GetStdHandle, HeapAlloc, CreateThread, GetExitCodeThread, HeapFree등의 함수는 모두 WIN32API이다.

SUMINFO 구조체는 스레드에게 작업 내용을 지시하기 위하여 사용한다. 멤버변수 a에서 b까지의 합을 구한 후 s에 대입한 후 화면에 출력하였다.


문자열을 콘솔 화면에 출력하는 WriteString함수는 WriteFile API를 이용하여 작성하였다. WriteString 함수의 마지막 인자(... 또는 va_list)는 인자의 데이터 형과 개수가 정해져 있지 않다.


main 함수에서는 처음에 콘솔화면에 출력하기 위한 기본 콘솔 스크린 버퍼 오브젝트의 핸들을 얻어온 후, GetProcessHeap API 리턴값인 기본 힙 오브젝트 핸들을 사용하여 SUMINFO 구조체의 크기만큼 힙 메모리 영역을 할당한다. 여기서 할당된 메모리 영역은 CreateThread의 인자를 통해서 생성될 스레드 함수로 전달된다.

일단 CreateThread 함수가 성공적으로 리턴하게 되면, 스레드 함수인 Sum함수가 실행된다.

위 예제 프로세스는 이 순간부터 2개의 스레드를 가진 프로세스가 된다.



결과값 :



반응형
Comments