본문 바로가기

프로그램-잉/C++

스레드 만들기

이번에는 지난번에 배운 멤버함수포인터를 응용하여

스레드를 만들어 보겠습니다.

 

일단 가장 간단하게 스레드를 만들어 볼건데요

우선 스레드를 사용하기 위해서 Windows.h를 포함시킵니다.

 

#include <iostream>
#include <windows.h>
using namespace std;

DWORD __stdcall foo(void* p)
{
    return 0;
}

int main()
{
    CreateThread(0,0,
    foo, //스레드로 수행할 함수
    (void*)"A", //스레드 함수로 보낼 인자.
    0,0);
}

간단한 코드인데요 DWORD나 __stdcall은 윈도우즈에서 사용하는것들인데 중요한게 아니니 넘어갈게요

메인 함수에 CreateThread를 보면 3번째 4번째 패러미터가 중요합니다. 쉽죠

 

하지만 이건 객체지향인 C++이 아니라 C 스타일이죠

그럼 지금부터 이것을 객체지향스타일로 바꿔보겠습니다.

 

class Thread
{
public:
    void run()
    {
        CreateThread(0, 0, threadMain, (void*)this, 0, 0); //필요한 this를 인자로 넘김
    }
    
   // 1. 아래함수는 Static이야 함
   // 2. 아래함수는 this가 없어 함수 인자로 전달.
    static DWORD __stdcall threadMain(void *p) //스레드로 넘겨주는 함수는 반드시 보이드 포인트 하나만 있어야한다 그러나 멤버함수는 this*가 숨겨져있음
    {
        Thread* const self = static_cast<Thread*>(p); //패러미터로 받은 this를 캐스팅
        self->Main(); //가상함수 호출
                      // this->Main() => Main(this)
        return 0;
    }
    virtual void Main() {} // void Main(Thread* const this)
};

 

위 코드 인데요

핵심은 2가지 입니다.

1. 스레드에 함수를 전달하기 위해서는 인자가 오직 void* 하나만 있어야하기 때문에 this* 숨겨져있는 멤버함수는 전달이 불가합니다.

2. 이를 위해 함수를 Static으로 만들어야 하는데 그러면 함수안에서 필드나 멤버함수접근이 불가능하기 때문에 CreateThread.의 인자로 this*를 넘겨줍니다 그러면 스레드에 전달된 함수는 이를 받아 캐스팅하여 사용합니다.

 

스레드를 이렇게 사용하는건 아주 유명한 패턴인데요

Android운영체제 내부에서도 이런방식으로 스레드를 처리합니다.

 

이 정도면 this* 잊지 못하겠네요

 

감삽니다.

'프로그램-잉 > C++' 카테고리의 다른 글

타이머 만들기  (0) 2020.11.03
멤버함수 포인터  (0) 2020.10.27
[C++] Method Call  (0) 2020.10.26
VS Code C++ 17 사용법  (0) 2020.10.25
VS Code에서 Boost Library 사용법  (0) 2020.10.24