2011-01-03 6 views
38

몇 가지 조사를 해본 결과, boost :: thread 개체를 만들고 "this"를 사용하여 비 정적 클래스 함수로 시작하고 부스트를 시작할 수 있음을 알았습니다 :: bind 등등. 실제로 나에게 많은 의미가 없다. 그리고 찾을 수있는 모든 예제는 boost :: thread 객체가 시작된 함수와 동일한 클래스 내에서 시작되었다. 그러나 나는 다른 클래스의 스레드를 시작하여 "this"를 사용하여 두려워한다. "this"는 함수를 포함하는 클래스가 아니라 스레드를 만드는 클래스의 것입니다. 나는 틀렸어. 나는이 "이"녀석에 대해 더 많이 알 필요가있다.) 다음은 문제를 겪고있는 출처의 예입니다.부스트 스레드 및 비 정적 클래스 함수 사용하기

ANNGUI.h

 
class ANNGUI 
{ 
private: 
    boost::thread *GUIThread; 
    Main *GUIMain; 
public: 
    // Creates the entire GUI and all sub-parts. 
    int CreateGUI(); 
} 

ANNGUI.cpp는

 
int ANNGUI::CreateGUI() 
{ 
     GUIMain = new Main(); 
    GUIThread = new boost::thread(GUIMain->MainThreadFunc); 
}; 

이 모든 소스가 아니라 내 문제가 여기 어딘가에서 생각, 나는 내가 처리해야 알 "이"어떻게 든,하지만 나는 잘 모르겠다. 나는 정적 함수를 사용할 수 있었지만, 실제로 변수를 정적으로 만들고 싶지는 않았다. 감사합니다. .

또한 부스트 라이브러리를 사용하기에 좋은 리소스가 있습니까? 그들의 웹 사이트 문서는 좋지만 내 머리 위로 보인다.

답변

73

this 키워드는 boost::bind 사용됩니다 당신이 만드는 함수 객체가 객체의 멤버 함수에 바인딩됩니다. 멤버 함수는 인스턴스와 별도로 존재할 수 없으므로 boost::bind 멤버 함수에서 펑터 개체를 만들 때 인스턴스에 대한 포인터가 필요합니다. 정확히 this 키워드가 실제로 무엇입니까. 키워드를 클래스의 멤버 함수 내에서 사용하는 경우 해당 클래스의 현재 인스턴스를 가리키는 포인터입니다.여기

int main() 
{ 
    Foo f; 
    boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, &f)); 
} 

, 우리는 우리의 스레드 함수로 푸 :: some_function를 사용 : 당신이 외부 에서 클래스 멤버 함수를 bind를 호출한다면

, 당신은 뭔가처럼 말할 수있다. 하지만 bindmain에서 호출하기 때문에 this을 사용할 수 없습니다. 그러나 같은 일과 같이, 우리는 푸의 멤버 함수 내에서 bind라고하면 this을 사용하여 달성 될 수있다 :

void Foo::func1() 
{ 
    boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, this)); 
} 

멤버 함수는 정적, 또는 단순히 일반 (비회원) 함수의 경우

, 인스턴스 포인터가 전혀 필요 없다.

boost::thread* thr = new boost::thread(some_regular_function); 
+2

'new'는 절대적으로 필요합니까? 일반 로컬 변수로 스레드를 만들면 작동하지 않습니까? –

+0

만약 내가 부스트 :: 스레드 * thr = 새 부스트 :: 스레드 (부스트 :: 바인딩 (& Foo :: some_function,이)); 두번?? –

3

boost :: bind는 친구입니다 (가끔씩보기에는 힘들 수 있습니다)!

사용 GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain));

다음 MainThreadFunc 정회원합니다. 즉, 일반적으로하는 것처럼 인스턴스 변수를 직접 사용할 수 있습니다. 이 같은

뭔가 :이 같은 경우

class GUIMain { 
public: 
    GUIMain() : m_Member(42) {} 

    void MainThreadFunc() { 
    // use all members as you would normally do 
    std::cout << m_Member << std::endl; 
    } 

private: 
    int m_Member; 
}; 
3

는 비 정적 멤버 함수 귀하의 경우 void MainThreadFunc(Main* this) 예를 들면, 첫 번째 매개 변수로 this을 무료 기능을 생각하는 데 유용합니다.

boost::thread는 인수 없음 펑터를 받아, 그래서 당신은 MainThreadFunc(GUIMain) 같은 될 것이라고, 그것을 인스턴스 GUIMain에 대한 참조를 포함하고 내가 위에서 설명한 바와 같이 본, GUIMain->MainThreadFunc를 호출 인수 없음 펑터를 통과해야합니다.

부스트 (그리고 이제는 TR1과 함께 C++도)는 그러한 펑터를 생성하는 도우미, 즉 boost::bind (또는 또는 boost::lambda::bind)을 제공합니다. boost::bind(f, arg1, arg2, ...)이라는 표현은 "f(arg1, arg2, ...)을 호출하는 무효 함수기 반환"을 의미합니다. 말했다

, 당신은 스레드를 생성하기 위해 다음 식을 사용할 수 있습니다

GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain)) 
+0

+1 부스트 :: 바인드를 사용해야하는 이유는 무엇입니까? –

+0

나는 boost :: bind에 의해 반환 된 functor가 어떻게 생겼는지 알지 못합니다. 당신의 정의에 따르면, Main :: MainThreadFunc (GUIMain)을 호출해야하지만,'MainThreadFunc'는 인자를 취하지 않습니다. 펑터는 내부적으로 어떻게 보이나요? –

39

다른 언급했듯이 새 스레드에서 개체 메서드를 호출하려면 해당 개체의 주소를 제공해야합니다. 이 방법은 현재 인스턴스의 주소를 얻기 위해 this를 사용하여 같은 클래스, 예를 들면 인 경우

GUIThread = new boost::thread(&Main::MainThreadFunc, GUIMain); 

:하지만이 같은 오버로드 boost::thread 생성자를 사용할 수 boost::bind를 호출 할 필요는 없습니다

t = new boost::thread(&myclass::compute, this); 

방법은 매개 변수가있는 경우 예를 들어, 두 번째 인수 후에을 지정할 수 있습니다

t = new boost::thread(&myclass::compute, this, p1, p2); 
+0

매우 포괄적입니다. 감사. – Michael

+0

왜 OP가 그 질문에'new'를 사용했기 때문에 단순히 GUIThread = boost :: thread (& Main :: MainThreadFunc, GUIMain); '.. – Pavel

+0

@Pavel을 사용하지 마십시오. 질문은 새 스레드에서 메소드를 호출하는 데 초점을 둡니다. 스레드 객체를 구성하는 방법을 여러 가지 방법으로 살펴 보는 것은이 질문과 관련이 없습니다. – maxschlepzig

1

이 객체가 쿵푸 경우 nctor, 즉 operator()이있는 경우이 인스턴스를 boost::thread에 전달할 수 있습니다. operator()은 고정 될 필요는 없습니다. 예 :

#include <boost/thread.hpp> 

struct th { 
    void operator()(); 
}; 

void th::operator()() 
{ 
    for (;;) { 
     // stuff 
    } 
} 

int main() 
{ 
    th t; 
    boost::thread my_thread(t); // takes a copy of t ! 
    my_thread.join(); // blocks 
    return 0; 
} 
관련 문제