본문 바로가기
C_C++ 프로그래밍

[Window Thread] 윈도우에서 쓰레드 간단한 예시

by RoJae 2019. 6. 25.



      로재의 개발 일기      

쓰레드 in 윈도우

윈도우에서 쓰레드를 사용하기 위해서는 리눅스와 다른 함수를 사용해야한다.

자세한 내용은 MSDN에서 확인 가능.


  CreateThread()

1
2
3
4
5
6
7
static HANDLE CreateThread(
    LPSECURITY_ATTRIBUTES lpsa,
    DWORD dwStackSize,
    LPTHREAD_START_ROUTINE pfnThreadProc,
    void* pvParam,
    DWORD dwCreationFlags,
    DWORD* pdwThreadId) throw();
cs

Thread를 생성하는 함수이다.

    ipsa : 새로운 thread의 보안 속성
    dwStacksize : 새로운 thread의 stack
    pfnThreadProc : 새로운 thread의 프로시저 즉 함수
    pvParam : (LPVOID) ThreadProc 프로시저에 넘길 parameter
    dwCreationFlags : 0이면 즉시 실행 CREATE_SUSPENDED 옵션이면 생성은 되지만 SUSPENDED 상태 멈춘다.
    pdwThreadId : 쓰레드의 id를 말한다.

  beginthreadex()

1
2
3
4
5
6
7
8
9
10
#include <process.h>
 
unsigned long _beginthreadex(
void* security, // Security Descriptor
unsigned stack_size, // initial stack size
unsigned (*start_address)(void*), // thread function
void* arglist, // thread argument
unsigned initflag, // createion option
unsigned* thrdaddr // thread identifier
)
cs

사실 당시 c 라이브러리가 개발이 되었을 때에는

멀티쓰레드 방식으로 프로그래밍은 매우 흔하지 않았다고 한다.

그래서 c 라이브러리에 있는 createThread()를 통해서 많은 쓰레드를 돌리면

연산 오류가 난다고 한다.

하지만 microsoft에서 제공하는 beginthreadex()를 통해서 이를 극복이 가능해졌다.


인자들의 내용은 createThread()와 아예 순서도 같고, 용도도 같다.

즉 적절한 형 변환만 해주면 사용할 수 있게 된다.


  Thread 예제

마지막으로 구조체를 사용한 간단한 Thread 소스코드를 첨부합니다.

(완벽하진 않아요 ㅠ)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include<stdio.h>
#include<Windows.h>
#include<tchar.h>
 
#define MAX_THREADS 10
 
DWORD STotal = 0;
 
// 생성될 Thread가 수행할 내용이 담긴 함수이다.
DWORD WINAPI ThreadProc(LPVOID IpParam);
 
struct threadData {
    int tid;
    char *msg;
};
 
// tchar 선언 후에 _tmain 선언
// _tmain은 unicode를 사용하지 않는 main을 말함
int _tmain(int argc, char *argv[]) {
    DWORD cntOfThread = 0;
    DWORD dwThreadID[MAX_THREADS];
    HANDLE hThread[MAX_THREADS];
    DWORD Total = 0;
    DWORD Result = 0;
 
    char msgg[] = "Create Thread";
    int id = 1;
 
    struct threadData *data = (threadData *)malloc(sizeof(struct threadData));
    data->msg = msgg;
 
    while (1) {
        // thread 총 10개 생성
        if (cntOfThread == MAX_THREADS) {
            _tprintf(_T("MAXIMUM THREAD NUMBER : %d\n"), cntOfThread);
            break;
        }
        data->tid = id++;
 
        // LPVOID는 쉽게 생각해서 (void *)이다
        // 유연한 자료형
        // thread의 id는 dwThreadID의 주소 값 => 각각의 쓰레드는 1씩 차이난다.
        hThread[cntOfThread] = CreateThread(NULL0, ThreadProc, (LPVOID) data, 0&dwThreadID[cntOfThread]);
        Sleep(1000);
 
        cntOfThread++;
    }
    Sleep(1000);
 
    for (DWORD i = 0; i < cntOfThread; i++) {
        GetExitCodeThread(hThread[i], &Result);
        Total += Result;
        CloseHandle(hThread[i]);
    }
 
    _tprintf(_T("Total :: %d \n"), Total);
    _tprintf(_T("Total :: %d \n"), STotal);
    system("pause");
    return 0;
}
 
DWORD WINAPI ThreadProc(LPVOID lpParam) {
    struct threadData *data = (struct threadData *) lpParam;
    printf("Create Thread %d\n", data->tid);
    //_tprintf(_T("Create Thread %d \n", data->tid));
    _tprintf(_T("Message : %s\n"), data->msg);
    STotal+=2;    // 전역 변수 접근 가능
    return (DWORD)lpParam;        // 리턴 값 전달 가능
}
cs

관련글


※ 본 글은 개인 포트폴리오 혹은 공부용으로 사용하기 때문에, 무단 복사 유포는 금지하지만, 개인 공부 용도로는 얼마든지 사용하셔도 좋습니다




댓글