Strategie für Event-Scheduler

Gast #3764273
Hallo,

ich suche eine Strategie oder einen Algorithmus der mir hilft folgendes 
umzusetzen:

Ich habe eine Liste an Events. Diese sollen jeweils mit einer bestimmten 
Zykluszeit "ausgeführt" werden. Jedes Event ist dabei gleich 
priorisiert.
Außerdem kann nur dann ein Event ausgelöst werden wenn gerade kein 
weiteres aktiv ist. D.h. das vorherige Event sollte fertig abgearbeitet 
worden sein bevor ein neues gestartet wird. Unter Umständen verzögert 
sich also ein Event leicht.
Dazu folgendes Beispiel:
1
ev_1  5ms
2
ev_2  30ms
3
ev_3  100ms

Hier sind die Zykluszeiten großzügig gewählt. Es sollte also wenig 
Probleme geben. ev_2 und ev_3 werden natürlich nicht genau zum Zeitpunkt 
t=30ms oder t=100ms ausgeführt weil das schnelle ev_1 dort auch jeweils 
aktiv ist. Wie gesagt, dieses leichte Delay ist in Ordnung. Gehen wir 
davon aus, die Eventliste wird jede Millisekunde geprüft, so findet ev_2 
bei t=31ms und ev_3 bei t=101ms statt. Passt.

Ok, nun folgendes (problematisches) Beispiel:
1
ev_1  5ms
2
ev_2  10ms
3
ev_3  10ms
4
ev_4  5ms
5
ev_5  5ms
6
ev_6  5ms

Hier wird schon durch die bloße Anzahl der Events erreicht, das die 
Zykluszeit nicht mehr eingehalten werden kann. Zwar unschön, aber nun 
gut.
Allerdings: die Verzögerungen werden sich aufaddieren, und irgendwann 
wird dann ein Event "verschluckt", d.h. geht verloren.
Das ist zwar noch weniger schön, aber immer noch akzeptabel.
Was aber nicht sein darf ist, dass ein Event was relativ spät in der 
Liste auftaucht (z.B. ev_6) gar nicht mehr ausgeführt wird.
Ich muss sicherstellen, dass jedes Event selbst bei hoher "Eventlast" 
irgendwann drankommt.

Gibt es da eine günstige Strategie/Algorithmus?
Mein Ansatz wäre: ich merke mir die Position in der Liste des zuletzt 
ausgeführten Events.
Ich teste meine Liste jede Millisekunde auf anstehende Events. Dabei 
arbeite ich die Liste nicht von [0] bis [n-1] durch sondern starte 
jeweils bei der gemerkten Position. So wird früher oder später das Ende 
der Liste erreicht.

Leider fehlen mir die mathematischen Grundlagen um diesen Ansatz 
bewerten/mit anderen vergleichen zu können.

Wär meine Lösung praktikabel oder gibt es da bessere Ansätze?
Ein Betriebssystem-Scheduler hat wohl ähnliche Probleme zu lösen (wenn 
auch ungleich komplexer). Von daher denke ich dass es da schon Ansätze 
gibt.

Viele Grüße
Man nimmt dazu eine timerschlange, also eine doppelt verkettete Liste, 
da ist erster parameter des gelinkten elementes die dauer vom voeriger 
her gespeichert. Nach abgearbeiteten Timer event wird der HW-timer auf 
die zu wartende Zeit gestellt. Der Timer arbeitet dann das jeweils 
anstehende Element ab. Einfuegen bedeutet nun sich von vorne hach hinten 
hangeln, und dann in die liste einfuegen.

etwa so ?
Statt einer Liste wär evtl. eine "priority queue" besser geeignet.
Die lässt sich einfach in ein Array mappen, also keine dynamische 
Speicherverwaltung nötig.
Abarbeiten/"pop" und Hinzufügen/"push" eines Jobs geht in O(log n), bzw. 
bei Array-Implementierung mit konstanter Länge: in O(1) ;)

Und schon ist sichergestellt, dass immer der dringenste Job an 
Array-Position 0 steht.


https://de.wikipedia.org/wiki/Vorrangwarteschlange
Gast
Meiner Ansicht nach, gehst Du bei der Analyse nicht gründlich genug vor.

Du musst drei Aspekte berücksichtigen:
1. Die Zykluszeit in der die Ereignisse tatsächlich auftreten.
2. Die reine Verarbeitungszeit der Ereignisse.
3. Die jeweilige maximal zulässige Reaktionszeit auf die Ereignisse.

Kennzeichne in Deinen Skizzen den Zeitablauf. Es wird nicht klar ob die 
in der ersten Skizze gezeigte Zeit die selbe ist, wie in der zweiten. 
(Ich kann mir zwar was dabei denken, aber es geht ja um ein tieferes 
Verständnis bei Dir).

Ein weiterer Aspekt ist die Frage der Unterscheidung zwischen Abläufen 
und Bedingungen, die aus irgendwelchen ausserhalb Deiner 
Einflussmöglichkeit liegenden Gründen so sind wie sie sind, oder weil 
sie so sein sollen, oder weil es wünschenswert ist, das sie so sind. Je 
nachdem ergeben sich weitere Überlegungen, die recht vielfältig sind. 
Nicht umsonst gibt es ganze Bücher über das Thema.
Gast
Bitflüsterer schrieb:
> Nicht umsonst gibt es ganze Bücher über das Thema.

Das ist mir bewusst.
Nicht umsonst treffe ich Annahmen, die das Problem vereinfachen:
- wenn die Zykluszeit nicht eingehalten kann stört dies nicht
- es sollen im laufenden Betrieb keine neuen Events eingereiht werden
- hauptsache, ein Event wird irgendwann erreicht
- die Bearbeitungszeit eines Events ist vernachlässigbar

Das hier ist ein Nebenkriegsschauplatz. Kein RTOS Scheduler dessen 
Verhalten streng deterministiech sein muss. Ich bitte das zu beachten.

Gibts dazu Ideen, die besser geeignet sind als meine Ursprüngliche?
Du musst dir schlicht merken, wann ein Event in "absoluter" Zeit dran 
ist. Dann prüfst du von mir aus jede ms, ob denn jetzt einer dran ist. 
Wenn ja, arbeitest du den ab, und merkst dir, wenn der wieder dran ist. 
Danach solltest du noch prüfen, ob noch mehr Events "jetzt" dran sind, 
und die auch abarbeiten. Wenn alle aktuellen durch sind, geht es von 
vorne los.

Oliver
Gast
Haro schrieb:
> Bitflüsterer schrieb:
>> Nicht umsonst gibt es ganze Bücher über das Thema.
>
> Das ist mir bewusst.
> Nicht umsonst treffe ich Annahmen, die das Problem vereinfachen:

Aus meiner Sicht machen sie es nicht einfacher. Man könnte sie klarer 
und strenger formulieren. Aber gut. Wenn es Dir reicht, soll es mir 
recht sein.

> Das hier ist ein Nebenkriegsschauplatz. Kein RTOS Scheduler dessen
> Verhalten streng deterministiech sein muss. Ich bitte das zu beachten.

Davon habe ich nichts geschrieben. Aus meiner Sicht schien es mir 
angebracht, erst einmal Grundlagen klarzustellen. Aber gut. Wenn Dir 
alles klar ist, soll es mir recht sein.

> Gibts dazu Ideen, die besser geeignet sind als meine Ursprüngliche?

Sicherlich. Ich hätte angenommen, das Du, um sie zu entwickeln und zu 
verstehen, ein paar Grundlagen anschauen solltest. Aber gut. Dir ist 
schon alles klar. Fehlt nur noch die Idee. :-)
Gast
Wie ich darauf gekommen bin, dass Du Grundlagen benötigst?

> Leider fehlen mir die mathematischen Grundlagen um diesen Ansatz
> bewerten/mit anderen vergleichen zu können.
Gast
Ok, schaun wir uns die Punkte an.

Bitflüsterer schrieb:
> Du musst drei Aspekte berücksichtigen:
> 1. Die Zykluszeit in der die Ereignisse tatsächlich auftreten.
> 2. Die reine Verarbeitungszeit der Ereignisse.
> 3. Die jeweilige maximal zulässige Reaktionszeit auf die Ereignisse.

1. Ich zeichne auf einer Zeitachse Punkte für die auftretenden Events. 
Dabei sehe ich, dass unter Umständen mehrere Eventtimer gleichzeitig 
abgelaufen sind. Abhängig von den einzelnen Zykluszeiten und der Anzahl 
Events. Erhöhe ich die Zykluszeiten so entspannt sich die Situation, bis 
irgendwann wieder alles i.O. ist. Habe ich mehr Events, verschärft sich 
die Situation.

2. Da ein Event nun keinen kurzen Impuls mehr darstellt sondern Zeit 
braucht verschärft sich die Situation. Das Bild aus 1. ändert sich nicht 
großartig, allerdings ist es jetzt schwerer, wieder in den grünen 
Bereich zu kommen.

3. Es gibt keinen "Timeout". Solange jedes Event irgendwann kommt passt 
alles. Ich vermute, wenn ich meinen Ansatz aus dem Eröffnungspost 
umsetze habe ich irgendwann folgendes Verhalten:
Mit jedem Zyklus verschlechtert sich die Situation. Die Delays summieren 
sich auf. Irgendwann sind alle Eventtimer gleichzeitig abgelaufen. Dann 
wird die Liste einfach der Reihe nach abgearbeitet, Zykluszeiten spielen 
keine Rolle mehr. Das System bleibt in diesem Zustand.

Sind meine Betrachtungen soweit richtig?
Ich sehe da wenig Optimierungspotential, aber ich könnte wohl mit der 
Lösung leben, außer es gibt noch Vorschläge ;-)
Haro schrieb:
> Irgendwann sind alle Eventtimer gleichzeitig abgelaufen. Dann
> wird die Liste einfach der Reihe nach abgearbeitet, Zykluszeiten spielen
> keine Rolle mehr.

Wenn das in Ordnun für dich ist, schlage ich vor, du versetzt das System 
gleich in den Zeitpunkt "Irgendwann", und arbeitest einfach alle Events, 
die dann gar keine mehr sind, hintereinander ab, ganz ohne 
Eventscheduler.

Oliver
Gast
Jo mei, natürlich wär eine gewisse Ordnung schöner. Momentan hab ich die 
halt nur bei günstigen Parametern, abhängig von Eventzahl und deren 
Zykluszeiten.

Da ich aber auf keine optimalere Lösung komme (siehe mein 
Gedankenexperiment im letzten Beitrag) und hier auch nix kommt werd ich 
das wohl so beibehalten. Nebenkriegsschauplatz eben.
Haro schrieb:
> Da ich aber auf keine optimalere Lösung komme (siehe mein
> Gedankenexperiment im letzten Beitrag) und hier auch nix kommt

Na ja, zum ganz große Töne spucken fehlt dir dann doch etwas die 
Substanz. Aber egal, wenn es sowieso egal ist, wann und warum da irgend 
etwas ausgeführt wird, mach einfach. Ist dein Programm.

Oliver

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 12 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.