Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access class variable from std::thread

I have the following class which kicks off a new std::thread. I now want the thread to access a member variable of the class. So far I cannot work out how to do this. In my MyThread function I want to check m_Continue.

I have tried passing in 'this' when the thread is created but I get an error:

Error 1 error C2197: 'void (__cdecl *)(void)' : too many arguments for call 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;
}

How can I do this??

like image 628
Harry Boy Avatar asked Feb 12 '23 23:02

Harry Boy


1 Answers

If you want to access this from within the thread function, then it shouldn't be static:

void MyThread();

Now you can simply pass this as the second thread constructor argument, as you tried; but, being a non-static member, you'll need to qualify its name:

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

Alternatively, you might find a lambda easier to read:

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

But you shouldn't muck around with pointers and new like that; make the member variable a thread object and initialise it in the initialiser list:

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

making sure to declare m_Thread after any other members that it accesses; and make sure you stop and join the thread in the destructor, or earlier.

Finally, m_Continue should be std::atomic<bool> in order to set it on one thread and read it on another with well-defined behaviour.

like image 193
Mike Seymour Avatar answered Feb 16 '23 01:02

Mike Seymour