Registriert: So Jan 07, 2007 21:26 Beiträge: 130 Wohnort: mal hier mal da mal irgendwo
Hi Leute, ja ich weiß das Thema klingt komisch aber mir is keine bessere kurze Umschreibung eingefallen Also es gehts um Folgendes, ich habe Ereignisse die in bestimmten Intervallen ausgeführt werden sollen. Kurzes Beispiel: Alle 2 Sekunden Textausgabe "Hallo" und alle 10 Sekunden "Test" ausgeben. Nun will ich daraus eine Liste machen die diese "Aufgaben" beinhaltet. Das Ergebnis zum Beispiel wäre: (2sec|"hallo",2sec|"hallo",2sec|"hallo",2sec|"hallo",2sec|"hallo",0sec|"test") Nun ist es aber so das ich nicht nur 2 Ereignisse hab sondern unterschiedlich viele und diese in einem Array habe. Nun fehlt mir komplett der Ansatz um das Umzusetzen. Quasi möchte ich einen Periodischen Intervall ermitteln. Ich hoffe ihr könnt mir weiter helfen, ich hocke schon seit 2 Wochen an diesem Problem
MfG bubble
_________________ Wenn Worte nichts als Worte sind, dann müssen's Steine sein! Solange - bis sie pleite sind - schmeißt Fensterscheiben ein! - Fidl Kunterbunt -
Registriert: Di Sep 06, 2005 18:34 Beiträge: 362 Wohnort: Hamburg
Hi,
also mir fällt da ein Algorithmus ein, in dem du die Aufgaben nach Intervall sortierst, dann immer den kürzesten in die Liste schreibts, das entsprechende Intervall von allen anderen abziehst und ihn dann wieder einsortierst.
Also angenommen, die Aufgaben liegen unsortiert in Liste A und du willst eine Liste B wie oben beschrieben erstellen ginge das etwa so:
Code:
sort(A) // nach intervall sortieren Auftrag tmp = A[0]; delete(A, tmp); add(B, tmp) // den Auftrag mit kleinstem Intervall an B anfügen forall(Auftrag auf in A) auf.intervall -= tmp.intervall; add(A, tmp)
Dabei muss darauf geachtet werden, am Ende immer den Auftrag mit seinem ursprüünglichen Intervall einzufügen (was ich hier weggelassen hab).
Das wird dann wiederholt, bis die gewünschte Länge bzw. eine bestimmte Abbruchbedingung erreicht ist.
Nur ein schneller Einfall, keine Ahnung ob das wirklich so richtig ist.
Gruß Shai
_________________ Der Mensch hat neben dem Trieb der Fortpflanzung und dem zu essen und zu trinken zwei Leidenschaften: Krach zu machen und nicht zuzuhören. (Kurt Tucholsky)
Schwabbeldiwapp, hier kommt die Grütze. (Der Quästor)
Also ich bin mir nicht sicher ob ich das hier richtig verstehe. Geht es dir darum diese Liste zu generieren oder wirklich die Aufgaben zum richtigen Zeitpunkt auszuführen? Ich nehme mal das letztere an, da das wahrscheinlicher ist. Falls du das erstere willst kannst du aber trotzdem weiter lesen. Ganz am Ende gehe ich nochmal darauf ein.
Was du brauchst ist z.B. ein Heap. Findet sich üblicherweise in der Standardbibliothek, brauchst du also wahrscheinlich nicht selbst implementieren. Ich kenne Delphi so gut wie nicht, also keine Ahnung wie das da heißt, aber in C++ wäre es z.B. ein std::priority_queue.
Ein Heap (zu deutsch: "Haufen") hat im wesentlichen nur drei Operationen: push : fügt ein neues Objekt in den Heap ein top : gibt das kleinste Element zurück pop : entfernt das kleinste Element aus dem Heap.
Wie der Heap letztlich intern funktioniert ist unwichtig. Es sei aber soviel gesagt das es sich letztlich um eine Art dynamisches Array handelt bei dem die Elemente auf eine spezielle weise sortiert gehalten werden. Durch geschicktes tauschen von Elementen wird vermieden ständig das gesamte Array neu zu sortieren. Bei Wikipedia findet sich dazu sicher was, falls Interesse besteht.
Für jeden Auftrag berechnest du einen Zeitstempel für den ersten Ausführungstermin des Intervalls. Da deine Intervalle recht kurz sind ist eine Millisekunden-Auflösung ratsam. Für Zeitstempel benutze ich hier einfach Zeit in Millisekunden seit einem bestimmten Datum. Welches Datum du nimmst ist Wurst. Um UNIX-konform zu sein könnte man etwa den 1. Januar 1970 00:00 Uhr UTC benutzen. In Windows ist da aber schwer dran zu kommen, zumindest wenn man Millisekunden-Auflösung möchte. Der Zeitpunkt des Programmstarts tut hier aber genauso gut.
Da ich wie gesagt kein Delphi kann, hier eine C++-Implementierung:
// Aufträge ausführen bis in alle Ewigkeit while (!heap.empty()) { uint64_t now = timestamp(); Auftrag* auftrag = heap.top(); // Erstes Element auf dem Heap if (now < auftrag->m_nextExecutionTime) { msleep(auftrag->m_nextExecutionTime - now); // Millisekunden sleep } heap.pop(); // Erstes Element löschen
So, wie versprochen...falls du doch das erstere willst, also nur die Liste generieren....dann geht das mit der gleichen Methode. Natürlich würdest du auf das sleep verzichten. Statt die tatsächliche Zeit zu benutzen verwendest du eine Variable. Wenn immer du einen Auftrag vom Heap nimmst addierst du seine Interval-zeit auf diese Variable...so als wäre diese Zeit vergangen. Die Abbruch-Bedingung würdest du in die reset-Methode einbauen, diese könnte etwa false zurückgeben wenn der Auftrag nicht erneuert werden soll.
In einer größeren Implementierung würde man natürlich die execute- und reset-Methoden virtuell machen damit Unterklassen diese überschreiben können.
P.S. Das war jetzt wahrscheinlich Overkill...aber damit kannst du problemlos 1000sende Aufträge gleichzeitig verarbeiten.
Registriert: So Jan 07, 2007 21:26 Beiträge: 130 Wohnort: mal hier mal da mal irgendwo
Hi, danke für die viele Hilfe. Coolcat, du hast recht, für das was ich jetzt damit vor hab ist deine Variante overkill. Aber für späteres auf jedenfall Interessant. Ich hab mir vorgestern schon mal Shaijans Beitrag durchlesen können, nur halt noch nicht zurückschreiben können :S Am besten gefällt mir die Variante von damadmax :] Simpel und leicht zu implementieren ^^
Leider bin ich aber auch erst wieder in ca. 2 Wochen zu hause um daran wirklich weiter arbeiten zu können. Bisher muss ich mich noch mit Block und Kuli zufrieden geben :S
MfG bubble
_________________ Wenn Worte nichts als Worte sind, dann müssen's Steine sein! Solange - bis sie pleite sind - schmeißt Fensterscheiben ein! - Fidl Kunterbunt -
Mitglieder in diesem Forum: 0 Mitglieder und 7 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.