QThread wait und sleep verständnis Problem

Alles rund um die Programmierung mit Qt
Antworten
geostein8888
Beiträge: 50
Registriert: 16. März 2011 08:25

QThread wait und sleep verständnis Problem

Beitrag von geostein8888 »

Hallo,
ich habe hier immer irgendwie anscheinend ein Verständnisproblem, ob es nun an meinem ENglish oder daher dass ich vorher nur Java programmiert habe kommt.

ich habe ein Programm, bei welchem auf Knopfdruck ein Thread gestartet wird, welcher dann alle Minute über eine Hashtable rennt und dort anhand von Zeitstempeln und der aktuellen Zioet entscheidet ob er einen Job starten muss oder einen der schon läuft beenden muss.

da ich das ganze nicht kontinuierlich benötige (die Hashtable ist nicht sehr gross dachte ich dass ich nach jedem Durcvhlauf ein wait bzw sleep von 60 sekunden mache. Und da kommt dann meine Problem, mache ich das, dann ist meine komplette Anwendung (auch der Hauptthread blockiert)

wird das unter QT irgendwie anders gemacht?

mfG
Georg
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Sowas macht man in Qt normalerweise mit einem QTimer. Dies könnte dann ein QTimer in einem (Q)Thread sein, oder auch nicht.

In diesem Fall würde ich auf einen Thread verzichten und lediglich mit einem QTimer (ohne Thread) arbeiten.

hth..
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Thread falsch gestartet, wait/sleep nicht vom Thread aus aufgerufen?
geostein8888
Beiträge: 50
Registriert: 16. März 2011 08:25

Beitrag von geostein8888 »

Hallo,
der Thread wird in einem Dialogwindow gestartet:

Code: Alles auswählen

this->schedulerManager = new MSMSchedulerManager(this,this->datahandler, this->properties, this->msmTools);
        this->schedulerManager->start();
die Run Methode des Threads sieht gekürzt so aus:

Code: Alles auswählen

void MSMSchedulerManager::run(){
    qDebug() << "MSMSchedulerManager: started";

    int checkCounter = 0;
    while (!this->stopped){

        QHashIterator<QString,Scheduler*> i(this->schedulerData);

        const QString dateFormat = "yyyy-MM-dd hh:mm";
        QDateTime actTS;
        actTS.currentDateTime();

        int timeoffsetSeconds = this->schedulerTimeOffset;
        QDateTime actOffsetLow = actTS.addSecs((-1*timeoffsetSeconds));
        QDateTime actOffsetHigh = actTS.addSecs(timeoffsetSeconds);

        while (i.hasNext()){
            i.next();
            QString guid = i.key();
            Scheduler *actEntry = this->schedulerData.value(guid);
            QString schedulerStatus = actEntry->getSchedAction();
            if (schedulerStatus == "r" || schedulerStatus == "isr"){
                //check only entries we have to recor or we are recroding right now
                QDateTime startTS = actEntry->getStartTS();
                QDateTime endTS   = actEntry->getEndTS();
                if (startTS < endTS){

                    //is in the timerange we have to start recording
                    if (schedulerStatus == "r"){
                        if (startTS <= actOffsetHigh && startTS >= actOffsetLow && endTS > actOffsetHigh){
                            //is to record
                          ...
                            emit this->signalChangeSchedulerStatus(guid,"isr");
                        }
                    } else if (schedulerStatus == "isr"){
                        if (endTS >= actOffsetHigh){
                            actEntry->setSchedulerStatus("reced");
                            emit this->signalChangeSchedulerStatus(guid,"reced");
                        }
                    }
                }
                //emit this->signalChangeSchedulerStatus(guid,checkCounterVar.toString());
            }
        }        
        qDebug() << "MSMSchedulerManager: sleep";
msleep(300);
    }
}
QTimer wollte ich nicht benutzen da es damit etwas zu umständlich ist die gestarteten Jobs auch wieder zur richtigen Zeit zu stoppen (der zeitpunkt kann sich während des Laufes ändern und kommt aus einer Datenbank)

Georg
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

hmm.. folgende Hinweise:
QTimer wollte ich nicht benutzen da es damit etwas zu umständlich ist die gestarteten Jobs auch wieder zur richtigen Zeit zu stoppen (der zeitpunkt kann sich während des Laufes ändern und kommt aus einer Datenbank)
Der Grund ist aus dem Code nicht ersichtlich.... das "msleep(300)" kann doch gut durch einen QTimer ersetzt werden? Und auch wenn dieser Takt ändern sollte, wäre doch ein neuer "start()"-Aufruf nicht wirklich "umständlich".. :roll:

Auch der Grund für den Thread ist nicht ersichtlich.. welche Methode ist hier denn blockierend (oder so aufwändig, dass sich ein Thread rechtfertigt?)?

Dann: die msleep(300) blockiert dir den Hauptthread sicher nicht (es sei denn, du rufst "run()" irgendwo noch im Hauptthread auf..). Du kannst aber mit "qDebug() << QThread::currentThread()" relativ gut prüfen, wo du dich in welchem Thread-Kontext befindet.

Weiteres: Falls die Blockaden im GUI-Thread als Anwender gut fühlbar sind, kannst du auch einfach bei der Blockade den Debugger anhalten und siehst dann ja, wo der GUI-Thread blockiert wird..

Weiters hoffe ich, du hast dein Konzept im Griff.. nicht dass da z.B. "Scheduler"-Instanzen parallel dazu gelöscht werden..

hth!
geostein8888
Beiträge: 50
Registriert: 16. März 2011 08:25

Beitrag von geostein8888 »

Hallo,
ein Thread aus dem Grund, da in selbigen wenn eine BEstimmte Zeit erreicht wurde jeweils ein VideoStream aufgezeichnet werden soll, und hier dann bis zu 4 parallel. Ich hatte die ganze Anwendung schon in Java fertig und dort funktionierte das ganze mit den Threads ausgezeichnet, nur konnte ich das ganze nicht zum Mac portieren und musste alles nocheinmal neu in QT/C++ anfangen.

Die Anwendung selbst funktioniert auch wie sie soll bis auf dieses eine Problem mit dem sleep(), welches mir meine komplette Application so lahm legt, dass ich den Taskmanager benötige um es abzuschiessen.

Georg
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Also dein Thread wird ja offensichtlich richtig gestartet (mit start(), nicht mit run() wie es gern falsch gemacht wird), und das sleep ist in run(). D.h. deine Applikation kann eigentlich nur hängen, wenn sie irgendwo auf den Thread wartet (welcher 60 Sekunden lang steht). Tut sie das?
Antworten