2014-09-25 81 views
2

我有以下類開始一個新的std ::線程。我現在想讓線程訪問類的成員變量。到目前爲止,我無法解決如何做到這一點。 在我的MyThread函數中,我想檢查m_Continue。從std :: thread訪問類變量

我試圖傳遞「這個」被創建,但我得到一個錯誤的線程時:

錯誤1個錯誤C2197:「無效(__cdecl *)(無效)」:對於呼叫c的參數太多:\ program files(x86)\ microsoft visual studio 11.0 \ vc \ include \ functional 1152 1 MyProject

class SingletonClass 
{ 
public: 
    SingletonClass(); 
    virtual ~SingletonClass(){}; 

    static SingletonClass& Instance(); 
    void DoSomething(); 
private: 
    static void MyThread(); 

    std::thread* m_Thread; 
    bool m_Continue; 
}; 

SingletonClass::SingletonClass() 
{ 
    m_Continue = true; 
    m_Thread= new std::thread(MyThread, this); 
} 

void SingletonClass::MyThread() 
{ 
    while(this->m_Continue) 
    { 
     // do something 
    } 
} 

void SingletonClass::DoSomething() 
{ 
    m_Continue = false; 
} 

SingletonClass& SingletonClass::Instance() 
{ 
    static SingletonClass _instance; 
    return _instance; 
} 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    SingletonClass& singleton = SingletonClass::Instance(); 
    singleton.DoSomething();  

    return 0; 
} 

我該怎麼做?

+0

無關:沒有理由動態地分配線程,'m_thread'可能僅僅是一個'的std :: thread'你分配:'m_thread = std :: thread {MyThread,this};'。而且,由於在SingletonClass :: m_Continue中的數據競爭,你的程序有未定義的行爲,因爲它可能會在生成的線程中被訪問,同時在主線程中被修改。您需要將其設爲'std :: atomic '或使用'std :: mutex'保護對它的訪問。 – Casey 2014-09-25 16:45:28

回答

4

如果你想從線程函數中訪問this,那麼它不應該是靜態的:

void MyThread(); 

現在,你可以簡單地傳遞this作爲第二thread構造函數的參數,你嘗試過;但是,作爲一個非靜態成員,你將需要限定它的名字:

m_Thread= new std::thread(&SingletonClass::MyThread, this); 

或者,你可能會發現一個lambda更容易閱讀:

m_Thread= new std::thread([this]{MyThread();}); 

但你不應該弄髒周圍用指針和new那樣;使構件變量thread對象,並在初始化劑列表初始化它:

SingletonClass::SingletonClass() : 
    m_Continue(true), m_Thread([this]{MyThread();}) 
{} 

確保任何其他成員,它訪問後申報m_Thread;並確保您停止並在析構函數中或之前加入該線程。

最後,m_Continue應該是std::atomic<bool>,以便將它設置在一個線程上,並在另一個線程上以明確的行爲讀取它。

2

替換

static void MyThread();

void MyThread();

作爲

this不能static方法內的訪問。

0

你可以訪問成員變量,如果它是公開的,或者你可以讓一個像「bool shallContinue()」這樣的方法返回m_Continue。

現在你是如何做到這一點。檢查以下修改的摘錄:

static void SingletonClass::MyThread(SingleTonClass *arg) 
{ 
    while(arg->shallContinue()) 
    { 
     // do something 
    } 
} 

下面一個完整的例子:

#include <iostream> 
#include <thread> 
#include <unistd.h> 
using namespace std; 

class A 
{ 
public: 
    A(int x) : a(x) 
    { 
     thr = new thread(myThread, this); 
    } 
    static void myThread(A *arg) 
    { 
     arg->show(); 

    } 
    void show() 
    { 
     cout << a << endl; 
    } 
private: 
    int a; 
    thread *thr; 
}; 

int main() 
{ 
    A a(1); 
    sleep(2); 
    return 0; 
} 
+0

您可以從成員函數訪問它,不管它是否公開。當你可以使它成爲非靜態的時,你爲什麼要使用'void *'參數? – 2014-09-25 16:47:42

+0

這只是快速打字。有很多方法可以實現靜態,非靜態等 – 2014-09-25 17:02:41