Zeitintensive Function in Thread "kapseln" ?

Alles rund um die Programmierung mit Qt
Antworten
comer352l
Beiträge: 47
Registriert: 10. Juli 2007 18:10

Zeitintensive Function in Thread "kapseln" ?

Beitrag von comer352l »

Hallo zusammen,

ich muss in meinem Programm mehrfach eine function aufrufen, die einige Sekunden benötigt, um den Rückgabewert zu liefern. Dabei handelt es sich um eine Read-Funktion, ueber die ich Daten von einem Messgerät abfragen kann (stammt aus einer externen Geräte-Bibliothek und kann daher nicht geändert werden).
Dabei friert mir natürlich jedesmal das GUI (QMainWindow) im Hauptthread ein.
Mein momentaner Ansatz besteht darin, dass Ganze in einem Thread zu kapseln, hier komme ich aber im Augenblick nicht weiter:
Ich möchte das Problem eigentlich nicht per Signals/Slots lösen, weil
1) die Read-Funktionan an den verschiedensten Stellen im Programm aufgerufen wird
2.) die Weiterverarbeitung des Rückgabewerts vom Verwendungs-Kontext abhängt
Das würde praktisch dazu führen, dass ich entweder unzählige zusäztliche Slot-functions brauche oder aber dem Thread Informationen darüber mit mitgeben muss, was mit dem Ergebnis (Rückgabewert) geschehen soll. Diese Informationen könnte dann der "empfangende" Slot des Hauptthreads auswerten. In jedem Fall würde das Programm aber dadurch sehr kompliziert bzw. unübersichtlich...
Es wäre also wünschenswert, den Rückgabewert in der gleichen Funktion auszuwerten, die auch die Read-Funktion aufruft.

Den Lese-Vorgang (Aufruf der Read-Funktion) in einem separaten Thread ablaufen zu lassen ist zwar 'ne leichte Übung, aber wenn ich mit wait()-Methode auf das Ende des Threads warte, friert mir mein GUI natürlich genauso ein...

Bin für jeden Lösungs-Ansatz dankbar...
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Über ein QCustomEvent könntest du den Empfänger mitgeben, event. ist dies leichter umzusetzen.
comer352l
Beiträge: 47
Registriert: 10. Juli 2007 18:10

Beitrag von comer352l »

Also ich habe das jetzt mal (vorläufig) so gelöst:
(Der Einfachheit halber habe ich das Problem im folgenden Beispiel auf eine einfache Warte-Funktion reduziert)

Code: Alles auswählen

class WThread : public QThread
{
   Q_OBJECT

private:
   int _ms;

public:
   WThread(int ms) { _ms = ms; };
   void run() { msleep(_ms); };
};


class WaitClass : private QEventLoop
{
   Q_OBJECT

public:
   WaitClass(int ms) : QEventLoop()
   {
      WThread wt(ms);
      connect( &wt, SIGNAL( finished() ), this, SLOT( exit() ) );
      wt.start();
      exec();
   };
};


class test
{
public:
    static void nbwait(int ms) { WaitClass wc(ms); };
};
Durch den Aufruf von

Code: Alles auswählen

test::nbwait(5000);
wird somit 5000ms gewartet, ohne dass das GUI einfriert (im Gegensatz zum direkten Aufruf von sleep()).
Ist zwar sicherlich nicht schön, klappt aber wunderbar...

In meinem konkreten Fall führe ich anstelle der sleep()-Funktion meine Read()-Funktion aus und es kommen noch die Rückgabewerte hinzu...

Bin dennoch weiter für jede Anregung dankbar !
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

bei sowas bluten mir die Augen.. aber wenn schon gebastel (sleep waehrend Applikation), dann eher so:

Code: Alles auswählen

void mySleep (int ms)
{
   QTime timer;
   timer.start();
   do {
          QCoreApplication::processEvents(QEventLoop::AllEvents, ms);
          QTest::qSleep(10);
   } while (timer.elapsed() < ms);
}
(aus QTest::qWait())

hth...
comer352l
Beiträge: 47
Registriert: 10. Juli 2007 18:10

Beitrag von comer352l »

solarix hat geschrieben:bei sowas bluten mir die Augen.. aber wenn schon gebastel (sleep waehrend Applikation), dann eher so:

Code: Alles auswählen

void mySleep (int ms)
{
   QTime timer;
   timer.start();
   do {
          QCoreApplication::processEvents(QEventLoop::AllEvents, ms);
          QTest::qSleep(10);
   } while (timer.elapsed() < ms);
}
(aus QTest::qWait())

hth...
Auch ein nettes Beispiel für 'ne Wait-Funktion... :D

Ich darf allerdings daran erinnern, dass es in meinem konkreten Fall nicht um eine (sinnlose) Warte-Funktion geht (sollte nur als vereinfachtes Beispiel dienen), sondern um eine Read-Funktion.

Die Idee mit dem Timer ist aber zumindest ein neuer Denk-Anstoss, den ich mir mal durch den Kopf gehen lassen werde... Danke !

Manchmal kommt man eben nicht ohne Bastelei aus.
Dass Grundproblem ist doch die schlecht bzw. falsch implementierte Read()-Funktion, die ich verwenden muss, und die ist leider fix... :(
Antworten