std::thread in Klasse mit Memberfunktion



  • #include <iostream>
    
    using namespace std;
    
    class test {
    private:
    void print() { 
    cout << "HI!" << endl;
    }
    public:
    void run() {
    //thread erstellen und laufen lassen
    
    //some stuff...
    }
    
    int main() {
    test Test;
    Test.run();
    
    return 0;
    }
    
    };
    

    Ich möchte in der run-Funktion der Klasse test einen Thread erstellen, der die print-Funktion ausführt. Dieser Thread soll aber nicht in der main-Funktion ausgeführt werden, da print ja private ist.



  • Shedex schrieb:

    Dieser Thread soll aber nicht in der main-Funktion ausgeführt werden, da print ja private ist.

    Threads werden nicht in einer Funktion ausgeführt und mit private hat das nichts zu tun.

    Du hast vergessen, eine Frage zu stellen.



  • dann musst du die "thread-variable" in der klasse unterbringen und in der run-methode einrichten/initialisieren und starten.



  • HansKlaus schrieb:

    dann musst du die "thread-variable" in der klasse unterbringen und in der run-methode einrichten/initialisieren und starten.

    Das wäre dann meine Frage, wie lautet der Syntax, um den thread zu initialisieren?



  • std::thread foo([&]() { print(); });
    


  • das wird ziemlich sicher ein std::terminate aufrufen.

    void run() {
      std::thread foo{[]() { print(); }};
      foo.join();
    }
    

    schon besser.

    (std::thread::~thread ruft std::terminate auf, wenn der thread joinable ist)

    abgesehen davon, muss man wohl auch sicherstellen, dass die instanz noch existiert, wenn der thread läuft. das wäre gleich der nächste fehler.

    //ouch, don't try this at home!
    struct Foo {
        int i;
    
        void bar() {
            std::thread t{[&]() { cout << "Hello!\n"; i = 5; }};
            //dasselbe problem gäbe es übrigens auch mit einem [=]-lambda
            t.detach();
        }
    };
    
    int main () {
        {
            Foo f;
            f.bar();
        }
    
        this_thread::sleep_for(1s);
    }
    


  • Interessante Sache, das mit dem Sicherstellen der Lebenszeit. Verwende in meinem Code etwas ähnliche wie das Folgende bei einer Klasse, die immer in shared_ptr gehalten wird:

    void foo() {
      auto sharedFromThis = shared_from_this();
      async([&, sharedFromThis]() { (void)sharedFromThis; bar(); });
    }
    

    Kann da der Compiler das copy-capture von sharedFromThis einfach wegoptimieren, wenn das Objekt nie verwendet wird?



  • Shedex schrieb:

    Das wäre dann meine Frage, wie lautet der Syntax, um den thread zu initialisieren?

    [quote=http://www.cplusplus.com/reference/thread/thread/]

    // thread example
    #include <iostream>       // std::cout
    #include <thread>         // std::thread
    
    void foo() 
    {
      // do stuff...
    }
    
    void bar(int x)
    {
      // do stuff...
    }
    
    int main() 
    {
      std::thread first (foo);     // spawn new thread that calls foo()
      std::thread second (bar,0);  // spawn new thread that calls bar(0)
    
      std::cout << "main, foo and bar now execute concurrently...\n";
    
      // synchronize threads:
      first.join();                // pauses until first finishes
      second.join();               // pauses until second finishes
    
      std::cout << "foo and bar completed.\n";
    
      return 0;
    }
    

    [/quote]

    nur wie du das jetzt mit dem join machst, weiß ich nicht so direkt, da join ja den programmablauf blockiert.



  • Ich habe noch nie einen Anwendungsfall für std::thread in Anwendungscode gesehen. Die Leute eiern immer mit thread herum, weil das ja thread heißt, und wundern sich, wie einfach es sein kann, wenn ich das mit future und async zeige. Genauso ist es mit condition_variable , wenn Leute eigentlich promise wollen.

    Das ist die "Syntax", um in C++ einen Thread zu erzeugen:

    #include <iostream>
    #include <future>
    
    using namespace std;
    
    class test {
    private:
    	void print() {
    		cout << "HI!" << endl;
    	}
    public:
    	std::future<void> thread;
    
    	void run() {
    		thread = std::async(std::launch::async, [this]
    		{
    			print();
    		});
    	}
    };
    
    int main() {
    	test Test;
    	Test.run();
    
    	return 0;
    }
    

    Funktioniert einfach ohne shared_ptr , terminate s oder Data Races. Falls jemand Exceptions verwendet, bitte die Dokumentation zu async lesen.


Log in to reply