4 Stimmen

Auf Klassenvariable von std::thread zugreifen

Ich habe die folgende Klasse, die einen neuen std::thread startet. Jetzt möchte ich, dass der Thread auf eine Member-Variable der Klasse zugreift. Bisher weiß ich nicht, wie ich das machen soll. In meiner MyThread-Funktion möchte ich m_Continue überprüfen.

Ich habe versucht, 'this' beim Erstellen des Threads zu übergeben, aber ich erhalte einen Fehler:

Fehler 1 error C2197: 'void (__cdecl *)(void)' : zu viele Argumente für den Aufruf 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 )
    {
       // etwas machen
    }
}

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;
}

Wie kann ich das machen??

5voto

Mike Seymour Punkte 242473

Wenn Sie von innerhalb der Thread-Funktion auf this zugreifen möchten, sollte es nicht statisch sein:

void MyThread();

Jetzt können Sie einfach this als zweites thread-Konstruktorargument übergeben, wie Sie es versucht haben; aber da es sich um ein nicht statisches Element handelt, müssen Sie seinen Namen qualifizieren:

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

Alternativ finden Sie vielleicht einen Lambda-Ausdruck leichter lesbar:

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

Aber Sie sollten nicht mit Zeigern und new herumspielen; machen Sie das Elementvariablenmitglied zu einem thread-Objekt und initialisieren Sie es in der Initialisierungsliste:

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

Vergewissern Sie sich, dass Sie m_Thread nach allen anderen Elementen deklarieren, auf die es zugreift; und stellen Sie sicher, dass Sie den Thread im Destruktor oder früher stoppen und joinen.

Schließlich sollte m_Continue ein std::atomic sein, um es auf einem Thread zu setzen und auf einem anderen mit klar definiertem Verhalten zu lesen.

3voto

Ersetzen

static void MyThread();

durch

void MyThread();

da

this innerhalb einer static Methode nicht zugänglich ist.

0voto

Nipun Talukdar Punkte 4526

Sie können auf die Member-Variable zugreifen, wenn sie öffentlich ist, oder Sie können eine Methode wie "bool shallContinue()" erstellen, die m_Continue zurückgibt.

Wie machen Sie das jetzt? Überprüfen Sie das unten modifizierte Snippet:

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

Unten ein komplettes Beispiel:

#include 
#include 
#include 
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;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X