Probleme mit sleep

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
cole-hawk
Beiträge: 6
Registriert: 1. März 2010 13:12

Probleme mit sleep

Beitrag von cole-hawk »

Hallo.

Ich habe ein kleines Problem mit der sleep Funktion.
Und zwar habe ich eine Qt Oberfläche mit einem Start Button. Bei klick auf diesen Button soll eine Funktion aufgerufen werden die irgendetwas macht. Also habe ich den button(clicked) mit einem Slot verbunden in dem die Funktion aufgerufen wird. Das klappt auch alles wunderbar.

Nun möchte ich aber, dass die Funktion erst zu einer vorgegebenen Zeit (nach klick auf start) aufgerufen wird, also habe ich vor dem Funktionsaufruf im Slot noch ein bisschen Code hinzugefügt, welche die aktuelle Zeit von der vorgegebenen Startzeit abzieht, und die Differenz wartet.

Dabei wird "sleep" jedoch immer abgebrochen. Wenn beispielsweise 50 Sekunden gewartet werden soll, gehts trotzdem schon nach 3 Sekunden weiter...

Liegt es an der "hohen" Wartezeit? Kommt Qt oder der Slot damit nicht klar? Oder liegt es an sleep? Am Code kann ja fast gar nix mehr falsch sein... auch wenn ich nur mit unsigned int arbeite oder sleep(50) ausprobiere, schläft er nur wenige Sekunden.

Code: Alles auswählen


#include <unistd.d>
-----------------------
	int timeToStart = lineEdit_TimeToStart->text().toInt();

	gettimeofday(&tv,NULL);
	int currentSec = (int)tv.tv_sec;

	unsigned int time_diff_sec = timeToStart  - currentSec;	
	sleep(time_diff_sec);
	gettimeofday(&tv,NULL);
	
	std::cout << "TimeToStart: " 	<< timeToStart 	<< std::endl;
	std::cout << "currentSec:  " 	<< currentSec 	<< std::endl;
	std::cout << "time_diff_sec: " 	<< time_diff_sec 	<< std::endl;
	std::cout << "TimeAfterSleep: " << (int)tv.tv_sec << std::endl;

	// start sending signal (das ist die Funktino die aufgerufen werden soll)
	arm_device(socket);
Und hier noch ein Beispiel der Ausgabe:
TimeToStart: 1283414800
currentSec: 1283414731
time_diff_sec: 69
TimeAfterSleep: 1283414736

Wie man sieht wurden statt 69 Sekunden nur 5 gewartet...

Danke für jede Hilfe!!
Grüße
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

sleep + gui ist quatsch. Eigentlich ist sleep immer quatsch :P
Verwende einen Timer (QTimer, wenn du mit Qt unterwegs bist).

Code: Alles auswählen

void Widget::on_btn_clicked() {
    int msec = calc_time_to_wait();
    QTimer::singleshot(msec, this, SLOT(aufrufen_nach_timeout()));
}
Bis der Slot aufgerufen wird, kann die Gui bedient werden. Willst du verhindern, dass der User nochmal auf den Button klickt, oder andere bestimmte Elemente bedient, disable diese.
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Mal abgesehen von franzf's Post ... der zwar wirklich Recht hat, aber viel zu zaghaft ist (ich wuerd weitergehen und sagen, das sleep auch in Nongui Programmen nen Indiz fuer ein Mangel am techn. Design ist, in Multithread/Multiprozessing umgebungen sollte man auch ohne GUI besser ereignissorientiert arbeiten) !

welches sleep verwendest Du ? welchen Header bindest Du dafür ein ?
<time.h> ?

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

Beitrag von solarix »

Mal abgesehen, dass sleep (wie bereits erwähnt) zu 99.99% Quatsch ist:
'man sleep' hat geschrieben: BESCHREIBUNG
sleep() lässt den aktuellen Prozess schlafen bis seconds Sekunden abge‐
laufen sind oder ein Signal eintrifft welches nicht ignoriert wird.

RÜCKGABEWERT
Null, wenn die geforderte Zeit abgelaufen ist, oder die Anzahl der
Sekunden, die noch geschlafen werden sollte.
Was z.B., wenn der Qt-Eventloop das ALARM-Signal verwendet....?
cole-hawk
Beiträge: 6
Registriert: 1. März 2010 13:12

Beitrag von cole-hawk »

Hallo,

erstmal danke für all die Antworten.
Das hat mir schon sehr viel weiter geholfen. Habe mein Problem mit dem QTimer ersetzt und es funktioniert wunderbar. Danke franz'f!!! ;)

Da ich an anderen Stellen meines Programmes auch sleep() nutze, werde ich auch da mal über timer nachdenken. Bei den anderen sleeps soll immer die exakte µs Anzahl bis zur nächsten Sekunde gewartet werden, was bisher scheinbar auch keine Probleme bereitet hat, aber vielleicht läuft das mit dem Timer doch etwas zuverlässiger.
Blöd ist nur, dass (zumindest QTimer) nur msec annimmt und keine µsec...

Aber gut zu wissen, dass sleep nicht so der Bringer ist..

@ RHBaum: <unistd.h> ;)

Danke & Grüße,
Cole
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Selbst im Millisekundenbereich kommen die Timer-Signale nicht abslut exakt. Dass ein System im Microsekundenbereich exakt timert bezweifle ich (vor allem im Desktop-Bereich).
cole-hawk
Beiträge: 6
Registriert: 1. März 2010 13:12

Beitrag von cole-hawk »

Gut, dann weiß ich wenigstens, dass ich in die Genauigkeitsgeschichte nicht zu sehr reinsteigern sollte...
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

dass ich in die Genauigkeitsgeschichte nicht zu sehr reinsteigern sollte...
Doch kann man :-)
Ich hab hier messaufnehmer, die arbeiten angeblich auf mehrere ns genau :-)

DU musst Dir nur bewusst sein, dass wenn du SW funktionalitaet verwendest, die auf dem rtc register des Prozessors aufbaut:

- Die grauenhaft ungenau ist. die Quarze die die boardhersteller verwenden, haben die mieseste güteklasse die gibt meist. Dass heist deine Takte schwanken und driften, das ne wahre Freude :-)
- du bekommst nie den Fokus wenn du Ihn brauchst, sondern immer dann wenn der Scheduler meint das Du an der reihe bist (bei einem nicht echtzeitfaehigen BS). Deswegen sind timer/sleeps auch nie genau, egal wie man die implementiert ...

Das heisst du musst die zeiten immer nachkorrigieren, und du musst die zeiten staendig gegen eine verlaessliche Referenzzeit korrellieren.

Dann klappts auch mit den nanosec :-) Naja fast ...
Die Guete der referenzzeit und die Laufzeiten, bzw Art und weise wie manche funktionen laufen, die du zum korrellieren verwendest, bestimmen am Ende die Güte deiner Zeitstempel :-)

Ciao ...
Antworten