Thread in Konstonstruktor starten



  • Hallo,

    ich weiß das die Frage recht simpel sein muss und ich eigentlich nicht hier danach fragen wollte. Aber nun habe ich schon einige Stunden danach gesucht und bin zu keinem Ergebniss gekommen. Die Suchmaschine meines Vertrauens hat mir nicht weiter geholfen, eben so wenig die zahlreichen YT Videos.

    Ich möchte in dem Konstruktor einer Klasse einen Thread starten welcher später im Destruktor gejoint wird. Dazu müsste ich ja den Thread vorher in der Klasse deklarieren, da er sonst ein Lokales Objekt in dem Konstruktor ist und im Destruktor nicht mehr bekannt. Wie kann ich das realisieren, dass der Thread einfach die ganze Zeit läuft solange die Instanz der Klasse existiert?

    Dazu habe ich die Klasse "thread" verwendet aus dem c++11 Standard.

    Hier im Forum habe ich folgenden Beitrag gefunden, welcher vom Titel her intressant war aber mir leider nicht weiter geholfen hat.
    https://www.c-plusplus.net/forum/331562?highlight=thread+klasse

    MfG,
    Rarebit.


  • Mod

    Wie kann ich das realisieren, dass der Thread einfach die ganze Zeit läuft solange die Instanz der Klasse existiert?

    Indem du den Thread entsprechend initialisierst und im Destruktor die join -Memberfunktion aufrufst?.

    struct A {
        std::thread t;
    
        A() : t([] {std::cout << "Moin";}) {}
    
        ~A() {t.join();}
    };
    


  • Die Lösung ist richtig, aber kann auch sehr gefährlich werden, da join eine Exception werfen kann.

    http://www.cplusplus.com/reference/thread/thread/join/
    http://www.codingstandard.com/rule/15-2-1-do-not-throw-an-exception-from-a-destructor/



  • Onkki schrieb:

    Die Lösung ist richtig, aber kann auch sehr gefährlich werden, da join eine Exception werfen kann.

    http://www.cplusplus.com/reference/thread/thread/join/
    http://www.codingstandard.com/rule/15-2-1-do-not-throw-an-exception-from-a-destructor/

    Auch std::threads ohne wrapper zu benutzen ist gefährlich da der Konstruktor in 32 Bit Systemen auch eine Exception werfen könnte, wenn das System keine weiteren Threads mehr starten kann.

    Was join angeht solltest Du im Destruktor auf auf joinable testen und ihn erst dann joinen.



  • Ruvi schrieb:

    Auch std::threads ohne wrapper zu benutzen ist gefährlich da der Konstruktor in 32 Bit Systemen auch eine Exception werfen könnte, wenn das System keine weiteren Threads mehr starten kann.

    Solange es nicht im Destruktor passiert wäre es aber auch kein Problem.



  • Ruvi schrieb:

    Onkki schrieb:

    Die Lösung ist richtig, aber kann auch sehr gefährlich werden, da join eine Exception werfen kann.

    http://www.cplusplus.com/reference/thread/thread/join/
    http://www.codingstandard.com/rule/15-2-1-do-not-throw-an-exception-from-a-destructor/

    Auch std::threads ohne wrapper zu benutzen ist gefährlich da der Konstruktor in 32 Bit Systemen auch eine Exception werfen könnte, wenn das System keine weiteren Threads mehr starten kann.

    Was join angeht solltest Du im Destruktor auf auf joinable testen und ihn erst dann joinen.

    Und nicht den Wrapper für den Wrapper vergessen!

    Execptions kann man auch im Code abfangen, dafür braucht es kein Wrapper Object, insbesondere kann man es damit nicht mal besser.



  • Bengo schrieb:

    Und nicht den Wrapper für den Wrapper vergessen!

    Execptions kann man auch im Code abfangen, dafür braucht es kein Wrapper Object, insbesondere kann man es damit nicht mal besser.

    Jo, jedes mal beim Starten eines Threads einen try, catch bauen und auch noch jedes mal im scope des Thread startens detach oder join mit Sicherheitstest machen ist natuerlich viel sinnvoller als einen generischen Thread wrapper. 🙄 Warum auch 10 Zeilen code schreiben wenn man stattdessen 300 schreiben kann.



  • wenn dein wrapper einen Fehler entedeckt muss er ihn behandeln, und das kann er im allgeinen nicht, in der Ebene dieses Wrappers und der Fehler muss nach außen. Also bringt er im Prinzip nichts.



  • Bengo schrieb:

    wenn dein wrapper einen Fehler entedeckt muss er ihn behandeln, und das kann er im allgeinen nicht, in der Ebene dieses Wrappers und der Fehler muss nach außen. Also bringt er im Prinzip nichts.

    Ich koennte wenn der std::thread Konstruktor eine exception wirft statt einem expliten neuen Thread dann einen std::async job starten der dann im current Thread ablaeuft oder eine explizite Exception aus dem Konsturktor des wrappers werfen fuer einen try catch der viel weiter oben sitzt, denn wenn das System out of threads gegangen ist hat man wahrscheinlich noch ganz andere Probleme.

    Ich bleib dabei die std::threads sind wie sie im Moment designed sind nicht dazu da ohne Wrapper benutzt zu werden.

    Das ist auch die empfohlene Herangehensweis die der Autor der Boost::Threads (Anthony Williams) empfiehlt.



  • Ich gehöre nun mal nicht zu den Leuten, die für alles einen Wrapper brauchen. Ich benutze meine integers auch lieber pur, und bei der std::thread finde ich es eigentlich abstract genug. Und ich bin mir nicht so sicher, ob ich dem wrapper bei fehlgeschlagenen thread irgenteine andere Lösung machen lassen möchte und das nicht lieber in der Ebene höher behandeln möchte.



  • Bengo schrieb:

    Ich gehöre nun mal nicht zu den Leuten, die für alles einen Wrapper brauchen. Ich benutze meine integers auch lieber pur, und bei der std::thread finde ich es eigentlich abstract genug. Und ich bin mir nicht so sicher, ob ich dem wrapper bei fehlgeschlagenen thread irgenteine andere Lösung machen lassen möchte und das nicht lieber in der Ebene höher behandeln möchte.

    Naja wir brauchen uns darueber jetzt nicht weiter darueber unterhalten aber einen wrapper fuer einen std::thread auf die selbe Stufe zu stellen wie einen wrapper fuer ein int finde ich schon ziemlich frech. :p


Log in to reply