이번에는 지난번에 배운 멤버함수포인터를 응용하여
스레드를 만들어 보겠습니다.
일단 가장 간단하게 스레드를 만들어 볼건데요
우선 스레드를 사용하기 위해서 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 |