2014-09-25 35 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