Alle 5 Minuten Aktion
-
Hallo!
Könnt ihr mir bitte schnell sagen wie ich alle 5 Minuten eine Aktion ausführen kann? Also eine Schleife, die um 10.05, 10.10, 10.15.. eine Aktion ausführt?MfG
Pferdi
-
Ja, wenn du allerdings nicht furchtbar übel programmieren willst (Implementierung mit Hilfe von Busy Waiting), dann solltest du dafür eine System-Library benutzen (Stichwort: Timer).
Sollten die 5 Minuten eine Echtzeitanforderung dann ist die Frage noch einmal anders zu behandeln bzw. eigentlich lautet die Antowrt trotzdem: System-Library.
MfG SideWinder
-
Pferdi schrieb:
Könnt ihr mir bitte schnell sagen
Schnell gesagt:
Thread, Timer, Eventsystem.
Wenn das zu schnell war musst du auch ein wenig Zeit investieren und uns z.B. zeigen was du bisher schon hast, welche Ansätze usw. Siehe auch den Thread in meiner Signatur.
-
for(;;) { DoAction(); Sleep(300000); }
-
Danke Icematix!
Naja aber, es soll so sein, dass es zu jeder fünften Minute der Stunde ausgeführt wird. Also z.B. um 15.55, 20.10...
-
Pferdi schrieb:
Danke Icematix!
Naja aber, es soll so sein, dass es zu jeder fünften Minute der Stunde ausgeführt wird. Also z.B. um 15.55, 20.10...Dann wartest du eben immer bis zum nächsten Fünfer.
Um die aktuelle Zeit rauszufinden:
http://www.cplusplus.com/reference/clibrary/ctime/time/
http://www.cplusplus.com/reference/clibrary/ctime/localtime/
-
Hat dein Programm einen bestimmten State, der alle 5 Minuten angepasst wird und der keinesfalls verloren gehen darf und vor allem recht rechenintensiv ist, um ihn wieder her zu stellen, oder geht es echt nur darum alle 5 Minuten z.B. eine Log-Datei nach Fehlern zu durchsuchen und in ne Datenbank zu schreiben oder Mails auf dem lokalen Mailserver abzuholen, oder ...
Falls ersteres musst du halt die aktuelle Uhrzeit nehmen, die Sekunden bis zur nächsten vollen 5 Minuten nehmen und Sleep damit bestücken, danach kannst du alle 5 Minuten deine Aktion ausführen. Wenn es exakt sein soll würde ich allerdings immer nach jeder ausgeführten Aktion die Sekunden neu berechnen, denn sonst passiert es, dass du irgendwann nicht mehr exakt um 20:55 sondern um einige Sekunden vorher/nachher dran bist.
Falls aber der State irrelevant ist, würde ich einen ganz anderen Weg einschlagen! Lass doch dein System automatisiert die Aktion durchführen. Unter Linux wäre die Lösung über einen cronjob. Dafür bracuhst du einen Cron-Daemon (dcron, fcron, vixie-cron, usw.) Für Windows hab ich jetzt auf die Schnelle Z-Cron gefunden. Schaus dir an ob dir das was bringt...
-
@l'abra d'or, danke, dass du dich meinem Problem annimmst. Es soll immer exakt alle 5 Minuten die Aktion durchgeführt werden. Jedoch soll es im Programm integriert sein. Folgendes ist mir eingefallen:
struct tm minutes; while(true){ if(minutes.tm_min % 5 == 0){ std::cout << "5 Minuten vergangen" << std::endl; } }Dies belastet meine CPU zu 50% und ist inakzeptabel. Wenn ich Sleep(1000) ans Ende der if-Schleife setze, ist das ganze zu ungenau.
-
Sleep(100) ? Sleep(10) ? Sleep(5) ? Sleep(1) ?
-
while(true){ if(minutes.tm_min % 5 == 0){ std::cout << "5 Minuten vergangen" << std::endl; Sleep(1); }Schon liegt die CPU auslastung bei 0%
-
Selbstverständlich sollte man noch die Time-Struct innerhalb der Schleife updaten.
-
Ok, Sleep(1) geht. Problem ist nur, dass "minutes" nicht aktualisiert wird.
Hat wer 'ne Idee, wie ich minutes aktualisieren kann?
-
-
Kann mir nicht schnell jemand sagen, wie ich minutes aktualisieren kann?
-
Pferdi schrieb:
Kann mir nicht schnell jemand sagen, wie ich minutes aktualisieren kann?
Sorry für die Ausdrucksweise aber...bist du doof oder nur unglaublich faul?
Hättest du auch nur einen Blick auf meinen Link geworfen, wäre es innerhalb von Sekunden klar gewesen.
time_t rawtime; struct tm * timeinfo; time ( &rawtime ); timeinfo = localtime ( &rawtime );
-
Icematix schrieb:
Pferdi schrieb:
Kann mir nicht schnell jemand sagen, wie ich minutes aktualisieren kann?
Sorry für die Ausdrucksweise aber...bist du doof oder nur unglaublich faul?
Hättest du auch nur einen Blick auf meinen Link geworfen, wäre es innerhalb von Sekunden klar gewesen.
time_t rawtime; struct tm * timeinfo; time ( &rawtime ); timeinfo = localtime ( &rawtime );Doch schon, so ähnlich hab ich's ausprobiert, nur meckert mein Compiler, wenn ich minutes als Zeiger verwende.
time_t actual; struct tm *minutes; time(&actual); while(true){ if(minutes.tm_min % 5 == 0){ cout << "5 Minuten vergangen" << std::endl; time(&minutes); minutes = localtime(&actual); } Sleep(1000); }Der Microsoft-Compiler sagt:
Links von ".tm_min" muss sich eine Klasse/Struktur/Union befinden. [if-Zeile] Typ ist 'tm *' Wollten Sie stattdessen '->' verwenden? 'time': Konvertierung des Parameters 1 von 'tm **' in 'time_t *' nicht möglich [time(&minutes);] Die Typen, auf die verwiesen wird, sind nicht verknüpft; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat.
-
Sleep(1) ist auch eine Methode, die context switches künstlich in die Höhe zu treiben

Bevor du das jetzt ernsthaft so machst:
for(;;) { DoAction(); time_t rawtime; struct tm* timeinfo; time(&rawtime); timeinfo=localtime(&rawtime); Sleep((timeinfo->tm_min/5*5+5-timeinfo->tm_min)*60-timeinfo->tm_sec+1)*1000); }
-
Edit: time(&minutes); soll natürlich time(&actual); heißen, das hat sich schonmal erledigt.
-
Nuja, hab alle Fehler gefunden...
time_t actual; struct tm *minutes; time(&actual); minutes = localtime(&actual); while(true){ if(minutes->tm_min % 5 == 0){ cout << "5 Minuten vergangen" << std::endl; Sleep(58000); } time(&actual); minutes = localtime(&actual); Sleep(2000); }
-
und woher kommt die magic number Sleep(58000);?
-
Und dir ist schon klar, dass deine Aktion alle zwei Sekunden ausgeführt wird, wenn du nicht gerade in einer Fünferminute bist?
Edit: auch noch mal aufgedröselt:
Sleep(( //aktuelle Minute auf Fünfer abrunden timeinfo->tm_min/5*5 //eine Fünferminute weiter als ob wir aufgerundet hätten +5 //wir wollen nur die relative Zeit, also aktuelle Minuten wieder abziehen -timeinfo->tm_min) //das warn Minuten, also jetzt Sekunden *60- //verstrichene Sekunden der aktuellen Minute sind ja schon vergangen, können wir also beim Warten weglassen timeinfo->tm_sec //jeweils zur 01-Sekunde ausführen, um eventuellen Ungenauigkeiten aus dem Weg zu gehen (Sleep setzt dich z.B. bei 49:59 ab oder so) +1 //jetzt Millisekunden )*1000);