관리 메뉴

Kim's Programming

쓰레드 생성 클래스화 하기 본문

Programming/팁

쓰레드 생성 클래스화 하기

Programmer. 2016. 3. 6. 14:07

쓰레드를 생성할때는 일반적으로는


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
#include<iostream>
#include<Windows.h>
DWORD WINAPI Calculate_SUM(LPVOID lpParam)//Sum Calculation Function for Thread
{
    std::cout << "print " << lpParam;
    return 0;
}
class process
{
private:
    HANDLE hThread[3];
    DWORD dwThreadID[3];
public:
    
    DWORD CreateThread_SUM()//Create SUM Threads
    {
        
        hThread[0= CreateThread(NULL, 0, Calculate_SUM,NULL, CREATE_SUSPENDED, &dwThreadID[0]);
        hThread[1= CreateThread(NULL, 0, Calculate_SUM,NULL, CREATE_SUSPENDED, &dwThreadID[1]);
        hThread[2= CreateThread(NULL, 0, Calculate_SUM,NULL, CREATE_SUSPENDED, &dwThreadID[2]);
        if (hThread[0== NULL || hThread[1== NULL || hThread[2== NULL)
            return 0;
    }
};
void main()
{
    process P;
    P.CreateThread_SUM();
}
cs

위와 같은 방식으로 짜게 되는데 우리는 쓰레드에서 쓰이는 Calculate_SUM 함수도 클래스 안에 넣고 싶어진다. 하지만 직접 넣게된다면 다음과 같은 경고를 볼 수 있다.


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
#include<iostream>
#include<Windows.h>
 
class process
{
private:
    HANDLE hThread[3];
    DWORD dwThreadID[3];
public:
    DWORD WINAPI Calculate_SUM(LPVOID lpParam)//Sum Calculation Function for Thread
    {
        std::cout << "print " << lpParam;
        return 0;
    }
    DWORD CreateThread_SUM()//Create SUM Threads
    {
        
        hThread[0= CreateThread(NULL, 0this->Calculate_SUM,NULL, CREATE_SUSPENDED, &dwThreadID[0]);
        hThread[1= CreateThread(NULL, 0this->Calculate_SUM,NULL, CREATE_SUSPENDED, &dwThreadID[1]);
        hThread[2= CreateThread(NULL, 0this->Calculate_SUM,NULL, CREATE_SUSPENDED, &dwThreadID[2]);
        if (hThread[0== NULL || hThread[1== NULL || hThread[2== NULL)
            return 0;
    }
};
void main()
{
    process P;
    P.CreateThread_SUM();
}
cs


위 처럼 클래스 내부에 넣은다음 this를 통해서 접근을 하면 다음 오류를 뿜어 냅니다.


1>------ 빌드 시작: 프로젝트: ConsoleApplication6, 구성: Debug Win32 ------
1>  소스.cpp
1>c:\users\dripb\documents\visual studio 2015\projects\consoleapplication6\consoleapplication6\소스.cpp(18): error C3867: 'process::Calculate_SUM': 비표준 구문입니다. '&'를 사용하여 멤버 포인터를 만드세요.
1>c:\users\dripb\documents\visual studio 2015\projects\consoleapplication6\consoleapplication6\소스.cpp(19): error C3867: 'process::Calculate_SUM': 비표준 구문입니다. '&'를 사용하여 멤버 포인터를 만드세요.
1>c:\users\dripb\documents\visual studio 2015\projects\consoleapplication6\consoleapplication6\소스.cpp(20): error C3867: 'process::Calculate_SUM': 비표준 구문입니다. '&'를 사용하여 멤버 포인터를 만드세요.
========== 빌드: 성공 0, 실패 1, 최신 0, 생략 0 ==========


이유를 찾아보니 Thread에 들어가는 함수는 비 멤버 함수이거나 정적 함수여야 한다고 합니다. 따라서 아래와 같이 static을 이용하여  함수를 선언하여 정적함수로 만들어 줍니다. static으로 선언하면 멤버 함수가 아니게 되어 정상적으로 빌드가 되게 됩니다. 하지만 일반적으로 우리는 클래스 안에 선언된 함수는 private 영역에 접근 할 수 있어서 편리하게 사용했는데 위와 같은 경우에는 private 영역에 접근 할 수는 없게 되어 매우 슬프게 됩니다. 그것을 해경하기 위해서는 LPVOID로 전달되는 파라메터를 이용하면 됩니다.


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
#include<iostream>
#include<Windows.h>
 
class process
{
private:
    HANDLE hThread[3];
    DWORD dwThreadID[3];
    DWORD Value;
public:
    static DWORD WINAPI Calculate_SUM(LPVOID lpParam)//Sum Calculation Function for Thread
    {
        process *This = (process *)lpParam;
        This->Value = 13;//접근 가능
        std::cout << "print " << lpParam;
        return 0;
    }
    DWORD CreateThread_SUM()//Create SUM Threads
    {
        
        hThread[0= CreateThread(NULL, 0this->Calculate_SUM,this, CREATE_SUSPENDED, &dwThreadID[0]);
        hThread[1= CreateThread(NULL, 0this->Calculate_SUM,this, CREATE_SUSPENDED, &dwThreadID[1]);
        hThread[2= CreateThread(NULL, 0this->Calculate_SUM,this, CREATE_SUSPENDED, &dwThreadID[2]);
        if (hThread[0== NULL || hThread[1== NULL || hThread[2== NULL)
            return 0;
    }
};
void main()
{
    process P;
    P.CreateThread_SUM();
}
cs


쓰레드 전달 파라메터를 this로 주고 쓰레드 생성시 사용하는 함수에 LPVOID로 전달된 것을 생성시 사용 함수가 포함된 클래스형 포인터로 변경하게 되면 비static 함수처럼 사용하면서 쓰레드 함수로도 사용할 수 있습니다.

'Programming > ' 카테고리의 다른 글

Overloading 과 Overriding의 차이  (0) 2016.03.08
DirectX SDK설치후 예제가 돌아가지 않는다.  (1) 2016.03.06