Seite 1 von 1
Warten auf Timer-Stop - welche Lösung ist die Beste ?
Verfasst: 10. Juli 2007 19:16
von comer352l
Hallo,
am besten schildere ich mein Problem/Vorhaben direkt an einem Beispiel-Code:
Code: Alles auswählen
class MyClass
{
Q_OBJECT
private:
QTimer *inittimer;
bool initsuccess;
public:
void init();
public slots:
void initTCB();
};
MyClass::MyClass()
{
initsuccess = false;
inittimer = new QTimer;
connect(inittimer, SIGNAL(timeout()), this, SLOT(initTCB()));
}
bool MyClass::init()
{
inittimer->start(5); // Timer starten: 5ms-Intervall
// AN DIESER STELLE SOLL GEWARTET WERDEN, BIS DER TIMER ANGEHALTEN WURDE
if (initsuccess)
return true;
else
return false;
}
void MyClass::initTCB()
{
// Hier erfolgt Initialisierung
...
initsucces = ... ; //
inittimer->stop(); // Timer anhalten
}
Kurz und präzise zusammengefasst: ich möchte einen QTimer starten und dann in der gleichen Function darauf warten bis dieser angehalten wird.
Am Timer führt kein weg vorbei, der Initialisierungsprozess sehr komplex und es ist nicht vorhersagbar, wie lange der Timer laufen muss bzw. wie oft initTCB() aufgerufen werden muss (daher wird der Timer auch von initTCB() selbst angehalten).
Ich habe noch nicht allzu viel Erfahrung mit C++ bzw. Qt. Gibts eine Möglichkeit, das Ganze einfach mit einem Signal zu lösen ? Hab' leider noch keine Möglichkeit gefunden, auf ein bestimmtes Signal zu warten !?
Habe auch schon überlegt, dass Ganze mit ein Event anzugehen, soweit ich das sehe wird aber beim Stop des Timers zumindest schon mal kein Standard-Event ausgelöst.
Mein dritter Gedanke wäre dann noch, das Ganze in einen Thread auszulagern...
Wie würdet ihr das lösen ? Bin für jede Anregung dankbar...
Gruß,
Frank
Verfasst: 10. Juli 2007 20:22
von upsala
Es gibt einmal das
timerEvent. Dann kann man den Timer mit einem Slot verbinden, so daß dieser nach Ablauf der Zeit angesprungen wird. Aber innerhalb einer Funktion kann man das nicht (sinnvoll) lösen.
Verfasst: 10. Juli 2007 23:14
von Burgpflanze
Warum machst du dann die Intitialisierung nicht gleich in der MyClass:init()?
Verfasst: 11. Juli 2007 18:35
von comer352l
Danke schon mal für eure Antworten !
Burgpflanze hat geschrieben:Warum machst du dann die Intitialisierung nicht gleich in der MyClass:init()?
Weil die Initialisierung exakt getimed erfolgen muß: Es muss u.A. eine Zeichenkette mit mit einem Byte-Abstand von 5ms bei einer Genauigkeit von 1ms gesendet werden ! Mit Pausen komme ich da nicht hin, ich bin schon happy, dass der QTimer das unter Windows auf die Reihe kriegt. Mit den Standard Timern der Windows-API kann man alles unter 20ms nämlich von vorneherein vergessen, und die Genauigkeit ist dabei noch mies...
Stichwort TimerEvent: hatte ich auch schon mal angedacht, auf ein Event kann ich ja mit QObject::timerEvent ( QTimerEvent * event ) warten. Es gibt aber wohl kein Standard-Event, dass beim TimerStop ausgelöst wird. Folglich müßte ich wohl ein eigenes Event definieren !?
Je mehr ich drüber nachdenke, um so mehr wird mir klar, dass ich ich den Unterschied zwischen einem Signal und einem Event wohl noch nicht wirklich verstanden habe...
Inwiefern unterscheidet sich denn in diesem konkreten Fall das verwendet timeout()-Signal von einem Timer-Event ??? Vielleicht kann mir ja jemand die Erleuchtung bringen...

Verfasst: 11. Juli 2007 19:10
von CaptnChaos
mach doch einen thread, der auf idle läuft und der immer den wert von deinem "initsuccess" abfragt und dann nachdem initsuccess auf true steht ein signal schiesst.
das signal verbindest du dann mit einem slot. und schon ist die sache geritzt.
d.H das letzte was du in deinem Konstruktor machst, ist den inittimer starten.

Verfasst: 11. Juli 2007 20:07
von upsala
Das eine ist QTimer-Signal und wird komplett über QTimer gesteuert, das andere ist der QObject-Timer und wird über QObject gesteuert.
Verfasst: 16. Juli 2007 13:06
von comer352l
Sorry, war ein paar Tage außerplanmäßig von Bord...
upsala hat geschrieben:Das eine ist QTimer-Signal und wird komplett über QTimer gesteuert, das andere ist der QObject-Timer und wird über QObject gesteuert.
Stimmt, aber QTimer erbt ebenfalls das timerEvent von QObject und verfügt somit über beides.
Ich denke, ich werde das Ganze mal mit einem Thread angehen. Falls jemandem doch noch eine elegantere Lösung einfällt...
Danke schon mal !
Verfasst: 16. Juli 2007 15:14
von LangerJan
EDIT: Meinen Vorschlag selbst ausprobiert - kannste knicken
Zeitkritische Programme schreiben sich besser in Low-Level Sprachen....leider.
Ist es dringend notwendig, dass du von init() den boolean zurückbekommst?
Verfasst: 16. Juli 2007 17:15
von solarix
Da muss ich meinem Vorposter recht geben:
LangerJan hat geschrieben:
Zeitkritische Programme schreiben sich besser in Low-Level
Der Kernel darf dich jederzeit (und besonders bei Sys-Calls wie du einer verwenden möchtest) unterbrechen und dich warten lassen. Etwas überspitzt gesagt: du kriegst die CPU nur auf goodwill des Kernels (mehrere Hundert (!) ms Verzögerungen bei periodischen Signals sind keine Seltenheit)
Echtzeit hast du nur mit entsprechenden Kernel-Erweiterungen oder direkt im Kernel-Space als Treiber. Und genau danach klingt deine Anwendung.
comer352l hat geschrieben:Mit Pausen komme ich da nicht hin, ich bin schon happy, dass der QTimer das unter Windows auf die Reihe kriegt.
Wo steht das?
Verfasst: 17. Juli 2007 13:53
von comer352l
comer352l hat geschrieben:Mit Pausen komme ich da nicht hin, ich bin schon happy, dass der QTimer das unter Windows auf die Reihe kriegt.
solarix hat geschrieben:
Wo steht das?
Ich hab's ausgiebig getestet !
solarix hat geschrieben:
Der Kernel darf dich jederzeit (und besonders bei Sys-Calls wie du einer verwenden möchtest) unterbrechen und dich warten lassen. Etwas überspitzt gesagt: du kriegst die CPU nur auf goodwill des Kernels (mehrere Hundert (!) ms Verzögerungen bei periodischen Signals sind keine Seltenheit)
Da hast du natürlich völlig recht und der Begriff "Echtzeit" ist ja auch eher als theoretischer Idealfall zu verstehen. Um jetzt nicht zu weit von Thema abzuweichen: Der Init-Prozess läuft bei mir in einem kleinen Testprogramm bereits sowohl unter Linux als auch Windows einwandfrei, und das auch bei erhöhter Systemlast. So mies ist der Windows-Scheduler dann doch nicht...

Verfasst: 17. Juli 2007 20:15
von solarix
comer352l hat geschrieben:
Ich hab's ausgiebig getestet !
aha.. sowas kommt selten vor

Aus reiner Neugierde: Welche Streuung bei wievielen Messungen ergab der Test?
comer352l hat geschrieben:
der Begriff "Echtzeit" ist ja auch eher als theoretischer Idealfall zu verstehen.
Naja... also das klang vorhin anderst:
comer352l hat geschrieben:
es muss u.A. eine Zeichenkette mit mit einem Byte-Abstand von 5ms bei einer Genauigkeit von 1ms gesendet werden !
das klang fuer mich sehr nach Echtzeit und Kernel.. nicht nach User-Space-Programm..
comer352l hat geschrieben:
So mies ist der Windows-Scheduler dann doch nicht...
Ich wollte nicht gegen Windows flamen

.. Linux und Solaris (trotz Echtzeit-Kern) hätten die gleichen Probleme.. Ich wollte nur die Frage beantworten: ausserhalb des Kernel-Spaces kannst du's lösen wie du möchtest: das ganze bleibt relativ zufällig. Und wenn ich's im User-Space implementieren müsste würde ich kaum Qt verwenden sondern z.B. Signals (Timer und sigpause).