QThread richtig einsetzen



  • Was soll die folgende Zeile machen???

    connect(m_pvAgilentWorker, &CAgilentLan::finished, m_pvWorkerThread, &QThread::quit);
    


  • wenn des Signals der Object CAgilentLan aufgerufen wird. dann muss der Thread zu ende sein.



  • QThread::quit() beendet die Eventloop in deinem Thread, falls vorhanden. QThread::terminate() kann threads wohl beenden. Wann das genau passiert ist wohl System abhängig
    Aber willst du das wirklich? Der Agilenten ist an den Thread gekoppelt und führt die Aktion aus der Klasse aus, ich denke nicht, dass das der Weg ist, wie das funktionieren kann.

    Außerdem glaube ich nicht, dass dein Agilenten Objekt das Signal emited, oder Emittenten sollte.

    Kleiner Tipp: Bau dir erstmal in einer Sandbox ein funktionierendes Beispiel mit einem QThread. Und versuche das dann auf deinen Agilenten zu übertragen.



  • Hallo zusammen,

    @Schlangenmensch

    Problem habe ich mittlerweile gelöst.
    Es reicht eigentlich vollkommen, wenn ich Signal/Slot verwende.
    Danke noch mal.



  • Ich nutze einfach mal den Thread hier weil ich ebenfalls ein Problem mit QThread habe.

    Ich nutze QThread folgendermaßen, um aufwändige Arbeit zu erledigen:

    TimeSeriesManager::TimeSeriesManager( QObject *parent ) :
        QObject( parent )
    {
        auto worker = new TimeSeriesLoader();
        worker->moveToThread( &thread );
    
        assert( QObject::connect( this, SIGNAL( sigLoadTimeSeries(std::shared_ptr<TimeSeries>)), worker, SLOT(onLoadTimeSeries(std::shared_ptr<TimeSeries>)) ) );
        assert( QObject::connect( worker, SIGNAL(sigTimeSeriesLoaded(std::shared_ptr<TimeSeries>)), this, SLOT(onTimeSeriesLoaded(std::shared_ptr<TimeSeries>)) ) );
        assert( QObject::connect( &thread, SIGNAL(finished()), worker, SLOT(deleteLater())));
        thread.start();
    }
    
    TimeSeriesManager::~TimeSeriesManager()
    {
        thread.quit();
        thread.wait();
    }
    

    D.h. der Thread läuft dauernd und bekommt über SIGNAL/SLOT seine Arbeit zugewiesen. Beim Start der Applikation bekommt der Thread so an die 2000 Jobs übertragen.

    Nun will ich die Anwendung beenden. Das Problem ist, dass der Thread trotz Aufruf von "quit()" erst noch seine Eventloop abarbeitet, d.h. die Anwendung endet erst, wenn der Thread alle seine Jobs abgearbeitet hat, was reichlich bescheuert ist.

    Gibt es eine Möglichkeit den Thread zu überzeugen, die Eventloop zu leeren?



  • Laut source nicht.

    Das ist recht spannend...der eventDispatcher scheint selbst einen QAbstractEventDispatcher::interrupt() zu "ignorieren"...

    Dir wird wohl nichts anderes uebrig bleiben als deinen eigenen QAbstractEventDispatcher zu schreiben.

    Edit: Hast du es bereits mit QThread::setTerminationEnabled und QThread::terminate probiert?



  • QThread::terminate gibt aber keine Garantie, wann und wo der Thread beendet wird. Könnte also mitten in einer Schreiboperation passieren, was zu einem inkonsistenten Zustand führen könnte.

    Wenn ich It0101 richtig verstehe, soll der Thread auch ruhig seinen aktuellen Job noch abarbeiten, nur die anderen 99, die noch in der Queue sind, nicht mehr, oder?



  • Schlangenmensch schrieb:

    Wenn ich It0101 richtig verstehe, soll der Thread auch ruhig seinen aktuellen Job noch abarbeiten, nur die anderen 99, die noch in der Queue sind, nicht mehr, oder?

    Genau das.
    Ich könnte auch das "wait" einfach weglassen und den Thread dann sterben lassen, während er noch läuft. Beim ShutDown der Applikation wäre das ja halb so schlimm.

    Aber ich will es halt möglichst ordentlich beenden. Daher das wait(). Leider wartet er mir etwas zu lange 😉



  • Ich finde es auch extrem befremdlich, dass QEventLoop keinerlei interrupt oder aehnliches zur verfuegung stellt...Ich meine, das wird doch vermutlich oefter benoetigt, wenn man unendliche queues laufen hat.



  • Dachte ich eigentlich auch...