Warterei in einen Thread auslagern
-
- Beiträge: 185
- Registriert: Fr 18. Jan 2013, 09:29
- OS, Lazarus, FPC: Windows 10, Windows XP, Lazarus 1.6
- CPU-Target: Celeron
Warterei in einen Thread auslagern
Hallo zusammen
Ich schreibe (noch immer) an einem Programm zur Steuerung einer Modelleisenbahn.
Zum Verständnis:
Das Programm besteht aus verschiedenen Proceduren die anhand einer mehrfach verketteten Liste die Fahrstrassen generiert.
Das funktioniert wunderbar.
Nun habe ich etwas für eine Modellbahn ungewöhnliches gebaut, nämlich einen Aufzug, mit dem ich einen klompletten Zug in eine andere Anlagenebene befördern kann.
Wenn ich nun eine Fahrstrasse einlaufen lasse, die mit dem Aufzug zu tun hat, muss ja nun getestet werden, ob dieser an der richtigen Stelle ist. Wenn ja, kein Problem, wenn nein, muss der Aufzug erst dorthin gefahren werden. Weiters auch kein Problem. Der Aufzug selbst meldet seine jeweilige Stellung über die COM Schnittstelle an den Hauptrechner.
Mir geht es jetzt aber um die Warterei.
Wenn ich das Ganze über eine Abfrageschleife realisiere blockiere ich damit das Hauptprogramm. Das Warten kann schon mal 30 Sekunden dauern.
Jetzt mal ein paar Fragen.
Ist es sinnvoll, diese Warteschleife in einen eigenen Thread auszulagern?
Wenn das gemacht wird, ist das Hauptprogramm dann weiter funktionsfähig?
Soll ich nur die Warteschleife auslagern?
Wenn Ja, wie mache ich das dann? Ich habe von Threadprogrammierung leider keine Ahnung .
Vielleicht geht das ganz einfach, vieleicht übersteigt das auch mein Niveau bei weitem.
Herzlichen Dank im Voraus für eure Bemühungen.
Ich schreibe (noch immer) an einem Programm zur Steuerung einer Modelleisenbahn.
Zum Verständnis:
Das Programm besteht aus verschiedenen Proceduren die anhand einer mehrfach verketteten Liste die Fahrstrassen generiert.
Das funktioniert wunderbar.
Nun habe ich etwas für eine Modellbahn ungewöhnliches gebaut, nämlich einen Aufzug, mit dem ich einen klompletten Zug in eine andere Anlagenebene befördern kann.
Wenn ich nun eine Fahrstrasse einlaufen lasse, die mit dem Aufzug zu tun hat, muss ja nun getestet werden, ob dieser an der richtigen Stelle ist. Wenn ja, kein Problem, wenn nein, muss der Aufzug erst dorthin gefahren werden. Weiters auch kein Problem. Der Aufzug selbst meldet seine jeweilige Stellung über die COM Schnittstelle an den Hauptrechner.
Mir geht es jetzt aber um die Warterei.
Wenn ich das Ganze über eine Abfrageschleife realisiere blockiere ich damit das Hauptprogramm. Das Warten kann schon mal 30 Sekunden dauern.
Jetzt mal ein paar Fragen.
Ist es sinnvoll, diese Warteschleife in einen eigenen Thread auszulagern?
Wenn das gemacht wird, ist das Hauptprogramm dann weiter funktionsfähig?
Soll ich nur die Warteschleife auslagern?
Wenn Ja, wie mache ich das dann? Ich habe von Threadprogrammierung leider keine Ahnung .
Vielleicht geht das ganz einfach, vieleicht übersteigt das auch mein Niveau bei weitem.
Herzlichen Dank im Voraus für eure Bemühungen.
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
Re: Warterei in einen Thread auslagern
Ich denke du solltest jede Strecke oder Zug in einen Thread auslagern. Sobald irgenein Zug auf einen Streckenabschnitt oder einen anderen Zug (Weiche) warten muss können sich die Threads gegenseitig blockieren.
Um einen Thread zu erstellen leitest du eine neue Klasse von TThread ab und überschreibst Execute.
Erstellen und Starten kannst den Thread dann mit
Blockieren würd ich mit TCriticalSection aus Syncobjs.
Eine Criticalsection kann immer nur einmal Betreten/verlassen werden.
Wenn du aus 2 Threads TCriticalsection.Enter aufrufst wartet der 2. bis der Erste Thread Criticalsection.Leave aufgerufen hat
Um einen Thread zu erstellen leitest du eine neue Klasse von TThread ab und überschreibst Execute.
Code: Alles auswählen
TMyWorkerThread = class(TThread)
public
procedure Execute; override;
end;
Code: Alles auswählen
procedure TMyWorkerThread.Execute;
begin
//Here we do work
DoSomeWork();
DoMoreWork();
//When we exit the procedure, the thread ends.
//So we don't exit until we're done.
end;
Erstellen und Starten kannst den Thread dann mit
Code: Alles auswählen
TMyWorkerThread.Create(false);
Blockieren würd ich mit TCriticalSection aus Syncobjs.
Eine Criticalsection kann immer nur einmal Betreten/verlassen werden.
Wenn du aus 2 Threads TCriticalsection.Enter aufrufst wartet der 2. bis der Erste Thread Criticalsection.Leave aufgerufen hat
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/
Re: Warterei in einen Thread auslagern
Ich weiss nicht, ob du hier undedingt Threads brauchst. Es kommt mMn sehr auf das Design deines Programmes an. Um eine Blockierung zu verhindern genügt es mitunter ein "Application.ProcessMessages;" in die entsprechende Schleife einzufügen.
Eine Modelleisenbahnsteuerung habe ich noch nicht gemacht, vermutlich würde ich aber auch wie Christian alle Züge in Threads stecken, ein Array oder eine Liste mit den Strecken vorhalten und die Threads per CriticalSection diese Strecken reservieren, sperren und frei geben lassen. Den Aufzug würde ich wie eine Strecke behandeln.
Eine Modelleisenbahnsteuerung habe ich noch nicht gemacht, vermutlich würde ich aber auch wie Christian alle Züge in Threads stecken, ein Array oder eine Liste mit den Strecken vorhalten und die Threads per CriticalSection diese Strecken reservieren, sperren und frei geben lassen. Den Aufzug würde ich wie eine Strecke behandeln.
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
- Maik81SE
- Beiträge: 308
- Registriert: Fr 30. Sep 2011, 14:07
- OS, Lazarus, FPC: Debian 12 (L 3.0.0.3 FPC 3.2.2); Windows 10 (L 3.99.0.0 FPC 3.2.0)
- CPU-Target: x86-64; arm; avr
- Wohnort: Lübeck
- Kontaktdaten:
Re: Warterei in einen Thread auslagern
Moin haderlump.
Ich kenne jetzt nicht die Hardware, welche dahintersteckt.
Aber wenn ich so ein Monster vor hätte, was ohne zweifel auch noch kommen wird, würde ich die externe Steuerung auf ein SPI/I²C/RS485-Netzwerk aussetzten, welches über einen µC verwaltet wird und somit.
Ergo.
Einen Befehlssatz schreiben, welcher in etwas so aussehen könnte.
%Sektor#%Option#%UseID#%On/Off/Analog
für eine Weiche als Bsp würde es ggf so aussehen können.
%Sektor
%01 <--- Schattenbahnhof
%Option
%01 <--- Weichen stellen
%02 <--- Signale setzten
%03 <--- Beleuchtung
%04 <--- Fahrt Vorwärts
%05 <--- Fahrt Rückwärts
%UseID
Nummer des Zieles
%On/Off/Analog
selbsterklärend
ergo man könnte von seinem PC die Befehl
%01%01%110%L
an den Externen µC schicken und dieser steuert dann das entsprechende Ziel an.
Wenn du nun allerdings eine Anlage Ähnlich wie Hamburg verwalten willst, dann könnte es sehr interessant werden
und ich würde mich gerne mit einbringe wollen.
Soweit erst mal mein Tipp, wie ich das lösen würde.
Ich kenne jetzt nicht die Hardware, welche dahintersteckt.
Aber wenn ich so ein Monster vor hätte, was ohne zweifel auch noch kommen wird, würde ich die externe Steuerung auf ein SPI/I²C/RS485-Netzwerk aussetzten, welches über einen µC verwaltet wird und somit.
Ergo.
Einen Befehlssatz schreiben, welcher in etwas so aussehen könnte.
%Sektor#%Option#%UseID#%On/Off/Analog
für eine Weiche als Bsp würde es ggf so aussehen können.
%Sektor
%01 <--- Schattenbahnhof
%Option
%01 <--- Weichen stellen
%02 <--- Signale setzten
%03 <--- Beleuchtung
%04 <--- Fahrt Vorwärts
%05 <--- Fahrt Rückwärts
%UseID
Nummer des Zieles
%On/Off/Analog
selbsterklärend
ergo man könnte von seinem PC die Befehl
%01%01%110%L
an den Externen µC schicken und dieser steuert dann das entsprechende Ziel an.
Wenn du nun allerdings eine Anlage Ähnlich wie Hamburg verwalten willst, dann könnte es sehr interessant werden
und ich würde mich gerne mit einbringe wollen.
Soweit erst mal mein Tipp, wie ich das lösen würde.
Code: Alles auswählen
label.caption:= 'gnublin.no-ip.info'
windows 10 (L 3.99.0.0 FPC 3.2.0)
-
- Beiträge: 185
- Registriert: Fr 18. Jan 2013, 09:29
- OS, Lazarus, FPC: Windows 10, Windows XP, Lazarus 1.6
- CPU-Target: Celeron
Re: Warterei in einen Thread auslagern
Danke für die Antworten.
Es geht aber hier nicht darum, Züge automatisch fahren zu lassen, sonder den Zugbetrieb zu steuern.
Die Anlage wird aus der Sicht eines Fahrdienstleiters gesteuert. Es wird eine Fahrstrasse eingestellt.
Dies umfasst das Routing innerhalb der Anlage.
Es wird der Startort und das Ziel vorgegeben, das Programm sucht dann selbst den günstigsten Fahrweg.
Es werden auch alle Weichen und Signale entsprechend gestellt.
Es wird ein (virtueller) Fahrregler aus einem Fahrreglerpool abgerufen und der Lok zugeordnet.
Zuguterletzt wird der Fahrbefehl an den Fahrregler gegeben.
Das alles ist schon fertig und funktioniert einwandfrei.
Die Erstellung der Fahrstrasse braucht nur Sekundenbruchteile.
Es sind auch keine festen Fahrstrassen vorgegeben, das Programm hängelt sich durch die Datenbank und findet den Fahrweg selbst.
Wenn ich eine neue Fahrstrasse einstellen möchte ist normalerweise die alte schon längst fertig.
Doch jetzt kommt als neue Komponente der Aufzug ins Spiel. Dieser kann nun gerade oben oder unten sein. Er meldet das auch an den Hauptrechner.
Eine Fahrstrasse, die den Aufzug berührt kann aber nur gehen, wenn der Aufzug die richtige Position hat. Er muss also dort hin fahren, und das kann 30 Sekunden dauern.
Wenn ich nun in der Fahrstrassenroutine auf den Aufzug warte, geht im Hauptprogramm nichts mehr.
Deshalb dieser Beitrag.
Ich bin aber nun auf Grund der Ausführungen auf eine Idee gekommen.
Ich könnte ja den Fahrstrassenaufruf in einen Tread packen.
Nun noch ein paar Fragen. lassen sich aus einem Tread heraus auch andere Proceduren aufrufen.
lässt sich eine Procedur die bereits in einem Tread aufgerufen wurde, nochmals aus einem anderen Tread aufrufen.
Beispiel:
Tread 1 Routing: Signal A -> W1 -> Gleis 3 -> Aufzug. Im Aufzug muss gewartet werden.
Tread 2 Routing: Signal B -> W23 -> Gleis1 - usw.
Es wird nun jeweils die Signaladressedes Startsignales an die Signalroutine überreicht.
Als nächstes wird die Weichenprocedur aufgerufen auch jeweils mit eigener Adresse usw.
Ich hoffe ihr versteht was ich meine.
Gruß Fritz
P.S. Dabei fällt mir ein, dass die Drehscheibe (die ich softwaremäßig noch "verarzten" muss) ja die gleiche Problematik hat.
Es geht aber hier nicht darum, Züge automatisch fahren zu lassen, sonder den Zugbetrieb zu steuern.
Die Anlage wird aus der Sicht eines Fahrdienstleiters gesteuert. Es wird eine Fahrstrasse eingestellt.
Dies umfasst das Routing innerhalb der Anlage.
Es wird der Startort und das Ziel vorgegeben, das Programm sucht dann selbst den günstigsten Fahrweg.
Es werden auch alle Weichen und Signale entsprechend gestellt.
Es wird ein (virtueller) Fahrregler aus einem Fahrreglerpool abgerufen und der Lok zugeordnet.
Zuguterletzt wird der Fahrbefehl an den Fahrregler gegeben.
Das alles ist schon fertig und funktioniert einwandfrei.
Die Erstellung der Fahrstrasse braucht nur Sekundenbruchteile.
Es sind auch keine festen Fahrstrassen vorgegeben, das Programm hängelt sich durch die Datenbank und findet den Fahrweg selbst.
Wenn ich eine neue Fahrstrasse einstellen möchte ist normalerweise die alte schon längst fertig.
Doch jetzt kommt als neue Komponente der Aufzug ins Spiel. Dieser kann nun gerade oben oder unten sein. Er meldet das auch an den Hauptrechner.
Eine Fahrstrasse, die den Aufzug berührt kann aber nur gehen, wenn der Aufzug die richtige Position hat. Er muss also dort hin fahren, und das kann 30 Sekunden dauern.
Wenn ich nun in der Fahrstrassenroutine auf den Aufzug warte, geht im Hauptprogramm nichts mehr.
Deshalb dieser Beitrag.
Ich bin aber nun auf Grund der Ausführungen auf eine Idee gekommen.
Ich könnte ja den Fahrstrassenaufruf in einen Tread packen.
Nun noch ein paar Fragen. lassen sich aus einem Tread heraus auch andere Proceduren aufrufen.
lässt sich eine Procedur die bereits in einem Tread aufgerufen wurde, nochmals aus einem anderen Tread aufrufen.
Beispiel:
Tread 1 Routing: Signal A -> W1 -> Gleis 3 -> Aufzug. Im Aufzug muss gewartet werden.
Tread 2 Routing: Signal B -> W23 -> Gleis1 - usw.
Es wird nun jeweils die Signaladressedes Startsignales an die Signalroutine überreicht.
Als nächstes wird die Weichenprocedur aufgerufen auch jeweils mit eigener Adresse usw.
Ich hoffe ihr versteht was ich meine.
Gruß Fritz
P.S. Dabei fällt mir ein, dass die Drehscheibe (die ich softwaremäßig noch "verarzten" muss) ja die gleiche Problematik hat.
- af0815
- Lazarusforum e. V.
- Beiträge: 6198
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Warterei in einen Thread auslagern
Ohne Thread, sehe ich die Möglichkeit, die Fahrstrasse mit dem Aufzug nur vorzubereiten aber nicht zu aktivieren bis der Aufzug in der richtigen Position ist. Das kann man auch über einen Timer erledigen. Der Timer prüft ob die ob eine vorbereiteter Auftrag da ist und ob die Vorausetzung erfüllt ist. Wenn nicht, warte er ganz einfach wieder oder er startet die vorbereitete Fahrstrasse.
Mit Timer ohne Thread gibt es auch keine Probleme mit der Datenübergabe zwischen den Routinen und den grafischen Elementen.
Wenn man Threads verwendet und grafische Objekte so muss man normalerweise sicherstellen, das nur der Hauptthread sich um die Elemente kümmert, zB. mittels Synchonize.
Andreas
Mit Timer ohne Thread gibt es auch keine Probleme mit der Datenübergabe zwischen den Routinen und den grafischen Elementen.
Wenn man Threads verwendet und grafische Objekte so muss man normalerweise sicherstellen, das nur der Hauptthread sich um die Elemente kümmert, zB. mittels Synchonize.
Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
- Maik81SE
- Beiträge: 308
- Registriert: Fr 30. Sep 2011, 14:07
- OS, Lazarus, FPC: Debian 12 (L 3.0.0.3 FPC 3.2.2); Windows 10 (L 3.99.0.0 FPC 3.2.0)
- CPU-Target: x86-64; arm; avr
- Wohnort: Lübeck
- Kontaktdaten:
Re: Warterei in einen Thread auslagern
Ja ich weiß Ganz genau, was du meinst
ich gehe mal von einer Strecke (3 Bahnhöfe) aus, wo der mittlere 5 gleise hat und 3 sind besetzt und als Bonus wird die Strecke von beiden seiten befahren.
Die komplette strecke ist selber 3 gleißig.
eine davon ist durch einen Güterzug blockiert.
Somit würden vom Startbahnhof (10 Gleisig) zum Zielbahnhof (6 Gleißig ---> Ziel Gleis 5) die Verwaltung in etwa so aussehen.
Setzte Alle weichen so, das Zug vom Gleich 9 (re.) auf fahrgleis (li) mit einer Geschwindigkeit 25% von Max. fährt.
bei erreichen vom Fahrgleis soll Speed auf 100% innerhalb von t = x erhöht werden.
Der zwischenbahnhof hat 2 Freie gleise. 3 & 4, wobei 4 vom gegenzug belegt werden soll.
Somit sind 2 weichen zu stellen, damit der Zug auf gleis 3 mit Speed = 50% nonstop durch fahren soll, danach werden wieder 2 Weichen gestellt (Fahgleis Li. Speed = 75%).
am Zielbahnhof werden im Vorfeld schon mal die Weichen und Signale vom Gleis 6 auf das mittlere Fahrgleis setzten und den zug auf reise schicken, mit dem ziel nächster Bahnhof Gleis 4.
ergo, dies geht komplett Ohne Thread.
ein Befehls. Zug1#Start#Ziel*Zug2#Start#Ziel.
Die Verwaltung selbst würde ich zur Speicher und CPU-Entlasung extern in die µC packen. wobei da auch alle Sensoren gelesen werden sollten.
Jemand einen anderen Ansatz?
Wenn ich mal etwas zeig habe versuche ich dies mal auf die Schnelle schreiben.
Könnte da aber dann ca eine paar Tage dauern, da ich die tage etwas eng in der zeit bin
Timer wie es Andreas sagt wirst du aber brauchen.
ich gehe mal von einer Strecke (3 Bahnhöfe) aus, wo der mittlere 5 gleise hat und 3 sind besetzt und als Bonus wird die Strecke von beiden seiten befahren.
Die komplette strecke ist selber 3 gleißig.
eine davon ist durch einen Güterzug blockiert.
Somit würden vom Startbahnhof (10 Gleisig) zum Zielbahnhof (6 Gleißig ---> Ziel Gleis 5) die Verwaltung in etwa so aussehen.
Setzte Alle weichen so, das Zug vom Gleich 9 (re.) auf fahrgleis (li) mit einer Geschwindigkeit 25% von Max. fährt.
bei erreichen vom Fahrgleis soll Speed auf 100% innerhalb von t = x erhöht werden.
Der zwischenbahnhof hat 2 Freie gleise. 3 & 4, wobei 4 vom gegenzug belegt werden soll.
Somit sind 2 weichen zu stellen, damit der Zug auf gleis 3 mit Speed = 50% nonstop durch fahren soll, danach werden wieder 2 Weichen gestellt (Fahgleis Li. Speed = 75%).
am Zielbahnhof werden im Vorfeld schon mal die Weichen und Signale vom Gleis 6 auf das mittlere Fahrgleis setzten und den zug auf reise schicken, mit dem ziel nächster Bahnhof Gleis 4.
ergo, dies geht komplett Ohne Thread.
ein Befehls. Zug1#Start#Ziel*Zug2#Start#Ziel.
Die Verwaltung selbst würde ich zur Speicher und CPU-Entlasung extern in die µC packen. wobei da auch alle Sensoren gelesen werden sollten.
Jemand einen anderen Ansatz?
Wenn ich mal etwas zeig habe versuche ich dies mal auf die Schnelle schreiben.
Könnte da aber dann ca eine paar Tage dauern, da ich die tage etwas eng in der zeit bin
Timer wie es Andreas sagt wirst du aber brauchen.
Code: Alles auswählen
label.caption:= 'gnublin.no-ip.info'
windows 10 (L 3.99.0.0 FPC 3.2.0)
- af0815
- Lazarusforum e. V.
- Beiträge: 6198
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Warterei in einen Thread auslagern
Eine Frage zum besseren Verständnis. Den Aufzug sehe ich wie einen Gleisblock der durch einen virtuellen Zug (Vorderzug) blockiert sein kann, bis er in der richtigen Lage ist. Somit müsste doch die Fahrstrasse aktiv sein können, nur das der Zug an entsprechnder Stelle durch die Signale angehalten wird bis der Aufzug (Block) frei ist. Oder ist bei dir eine Fahrtstrasse immer per se frei und es darf kein weiterer Zug im Bereich sein ?
Andreas
Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
- Maik81SE
- Beiträge: 308
- Registriert: Fr 30. Sep 2011, 14:07
- OS, Lazarus, FPC: Debian 12 (L 3.0.0.3 FPC 3.2.2); Windows 10 (L 3.99.0.0 FPC 3.2.0)
- CPU-Target: x86-64; arm; avr
- Wohnort: Lübeck
- Kontaktdaten:
Re: Warterei in einen Thread auslagern
af0815 hat geschrieben:Eine Frage zum besseren Verständnis. Den Aufzug sehe ich wie einen Gleisblock der durch einen virtuellen Zug (Vorderzug) blockiert sein kann, bis er in der richtigen Lage ist. Somit müsste doch die Fahrstrasse aktiv sein können, nur das der Zug an entsprechnder Stelle durch die Signale angehalten wird bis der Aufzug (Block) frei ist. Oder ist bei dir eine Fahrtstrasse immer per se frei und es darf kein weiterer Zug im Bereich sein ?
Andreas
Ich würde das durch 2 Miniaturlichtschranken abfragen.
eine am Sektionsanfang und eine am ende.
Wobei beide im Winkel von ca 30 bis 45 Grad zum gleis stehen sollten.
Edit
Ich setzt mich morgen mal ran und schreibe mal eine Liste mit den Sensoren/Aktoren für meinen Ansatz.
Vielleicht dann besser verständlich für alle
Code: Alles auswählen
label.caption:= 'gnublin.no-ip.info'
windows 10 (L 3.99.0.0 FPC 3.2.0)
-
- Beiträge: 185
- Registriert: Fr 18. Jan 2013, 09:29
- OS, Lazarus, FPC: Windows 10, Windows XP, Lazarus 1.6
- CPU-Target: Celeron
Re: Warterei in einen Thread auslagern
Danke für die Antworten
Es gibt in der Anlage ca. 30 Microprozessoren. Die Kümmern sich
a)um die Einsammlung von kontaktinformationen und deren Übergabe an den PC.
b) Die Ausgabe vom PC und Steuerung der Weichenantriebe.
Das sind aber praktisch nur Convertierungsaufgaben.
Zur Programmstruktur:
Es gibt für alle "Infrastrukturelemente" eine eigene Behandlungroutine.
Also eine Procedur die sich um allse Kümmert was Gleise betrifft
eine die sich um Weichen kümert eine für Signale. usw.
Wenn ein Fahrweg gesucht wird, wird natürlich überprüft ob die Elemente frei sind. Also Kein Fahrzeug drin, nicht für andere fahrstrassen verwendet, oder gesperrt.
Für den Aufzug gibt es natürlich das Kriterium "An der richtigenStelle".
Die meisten Punkte die ihr angesprochen habt, sind bereits geregelt.
natürlich kann ich den Aufzug vorher an die richtige Stelle fahren, und dann ergibt sich das Problem gar nicht erst.
Aber ich dachte halt es wäre raffiniert wenn sich der Rechner selbst darum kümmern könnte.
Es geht mir eigentlich nur darum dass während der Wartezeit keine weiteren Aktionen möglich sind.
Übrigens es gibt schon timergesteuerte Hintergrundroutinen die sich z. B um die Geschwindigkeitssteuerung oder die Verarbeitug der Kontaktinformationen kümmern. Aber das ist hier eigentlich unwichtig.
Im Übrigen liegt die Prozessorauslastung nomalerweise im Prommillebereich. Eine Überlastung ist selbst auf alten Krücken praktisch ausgeschlossen.
Gruß Fritz
Es gibt in der Anlage ca. 30 Microprozessoren. Die Kümmern sich
a)um die Einsammlung von kontaktinformationen und deren Übergabe an den PC.
b) Die Ausgabe vom PC und Steuerung der Weichenantriebe.
Das sind aber praktisch nur Convertierungsaufgaben.
Zur Programmstruktur:
Es gibt für alle "Infrastrukturelemente" eine eigene Behandlungroutine.
Also eine Procedur die sich um allse Kümmert was Gleise betrifft
eine die sich um Weichen kümert eine für Signale. usw.
Wenn ein Fahrweg gesucht wird, wird natürlich überprüft ob die Elemente frei sind. Also Kein Fahrzeug drin, nicht für andere fahrstrassen verwendet, oder gesperrt.
Für den Aufzug gibt es natürlich das Kriterium "An der richtigenStelle".
Die meisten Punkte die ihr angesprochen habt, sind bereits geregelt.
natürlich kann ich den Aufzug vorher an die richtige Stelle fahren, und dann ergibt sich das Problem gar nicht erst.
Aber ich dachte halt es wäre raffiniert wenn sich der Rechner selbst darum kümmern könnte.
Es geht mir eigentlich nur darum dass während der Wartezeit keine weiteren Aktionen möglich sind.
Übrigens es gibt schon timergesteuerte Hintergrundroutinen die sich z. B um die Geschwindigkeitssteuerung oder die Verarbeitug der Kontaktinformationen kümmern. Aber das ist hier eigentlich unwichtig.
Im Übrigen liegt die Prozessorauslastung nomalerweise im Prommillebereich. Eine Überlastung ist selbst auf alten Krücken praktisch ausgeschlossen.
Gruß Fritz
-
- Beiträge: 2013
- Registriert: Do 16. Okt 2008, 10:22
- OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
- CPU-Target: x86,x64,ARM
Re: Warterei in einen Thread auslagern
Hast du einen "state machine" Ansatz schon in Betracht gezogen?
https://de.wikipedia.org/wiki/Virtuelle ... er_Automat
https://de.wikipedia.org/wiki/Endlicher_Automat
Der state machine-Tick könnte ohne weiteres im main thread laufen und die Entwicklung und Wartung ist strukturierter als mit normalem "Softwaregewurstel".
Ich würde für einzelne Aufgaben je eine Sub-state-machine programmieren. Vielleicht mit einem flag das bei Änderungen getriggert wird, um im gleichen Tick auch alle Folgeänderungen zu bearbeiten.
Das Arbeiten mit threads hat so seine Tücken...
Martin
https://de.wikipedia.org/wiki/Virtuelle ... er_Automat
https://de.wikipedia.org/wiki/Endlicher_Automat
Der state machine-Tick könnte ohne weiteres im main thread laufen und die Entwicklung und Wartung ist strukturierter als mit normalem "Softwaregewurstel".
Ich würde für einzelne Aufgaben je eine Sub-state-machine programmieren. Vielleicht mit einem flag das bei Änderungen getriggert wird, um im gleichen Tick auch alle Folgeänderungen zu bearbeiten.
Code: Alles auswählen
repeat
changeflag:= false;
//call state machines
until not changeflag;
Das Arbeiten mit threads hat so seine Tücken...
Martin
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
Re: Warterei in einen Thread auslagern
Ich verstehe nicht warum alle solche Angst vor Threads zu haben scheinen. Man muss beim programmieren etwas aufpassen, aber grundsätzlich eine sehr schöne Sache.
Klar kann man alles auch im Hauptprogramm machen aber gerade bei Steuerungen find ich es sinvoll da man quasi weiter Linar programmieren kann. State Mashines sind nahezu unmöglich zu debuggen und hat man dort mal nen Fehler sucht man sich tot. Die gehören auf Microcontroller aber nicht auf Systeme auf denen man Prozesse/Threading zur verfügung hat.
Threads haben in diesem fall noch einen riesen Vorteil den man sonst selten hat, nämlich das es wenn ich das richtig verstehe Lineare Abläufe sind und keine unendlichen Schleifen. Man kann den Thread starten und vergessen. (Von Status Meldungen mal abgesehn). Alles in allem auch ein sehr schönes Problem um den Umgang mit Threads zu lernen.
Klar kann man alles auch im Hauptprogramm machen aber gerade bei Steuerungen find ich es sinvoll da man quasi weiter Linar programmieren kann. State Mashines sind nahezu unmöglich zu debuggen und hat man dort mal nen Fehler sucht man sich tot. Die gehören auf Microcontroller aber nicht auf Systeme auf denen man Prozesse/Threading zur verfügung hat.
Threads haben in diesem fall noch einen riesen Vorteil den man sonst selten hat, nämlich das es wenn ich das richtig verstehe Lineare Abläufe sind und keine unendlichen Schleifen. Man kann den Thread starten und vergessen. (Von Status Meldungen mal abgesehn). Alles in allem auch ein sehr schönes Problem um den Umgang mit Threads zu lernen.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/
-
- Beiträge: 2013
- Registriert: Do 16. Okt 2008, 10:22
- OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
- CPU-Target: x86,x64,ARM
Re: Warterei in einen Thread auslagern
Christian hat geschrieben: Mashines sind nahezu unmöglich zu debuggen und hat man dort mal nen Fehler sucht man sich tot.
Da mache ich gegenteilige Erfahrungen.
-
- Beiträge: 565
- Registriert: So 26. Aug 2012, 09:03
- OS, Lazarus, FPC: Windows(10), Linux(Arch)
- CPU-Target: 64Bit
Re: Warterei in einen Thread auslagern
State machines haben auch den Vorteil, dass nichts "gleichzeitig" passieren kann(!).
Ich finde, dadurch sind sie einfacher zu debuggen.
Threads haben zwar mehr technische Vorteile, aber sind um einiges komplexer.
(Mehr Arbeit, mehr Möglichkeiten).
MFG
Komoluna
Ich finde, dadurch sind sie einfacher zu debuggen.
Threads haben zwar mehr technische Vorteile, aber sind um einiges komplexer.
(Mehr Arbeit, mehr Möglichkeiten).
MFG
Komoluna
Programmer: A device to convert coffee into software.
Rekursion: siehe Rekursion.
Rekursion: siehe Rekursion.
-
- Beiträge: 153
- Registriert: Sa 30. Jan 2010, 18:17
- OS, Lazarus, FPC: Windows 10 64Bit/ lazarus 3.0 mit FPC 3.2.2 (32Bit + 64bit)
- CPU-Target: 64Bit
- Wohnort: Berlin
Re: Warterei in einen Thread auslagern
Nur passiert auf einer Eisenbahnanlage nicht nur eine Sache gleichzeitig. Sondern können mehere Dinge gleicchzeitig geschehen, die auch überwacht werden müssen.
Ich würde auch zu den Threads greifen. Hat auch den Vorteil, dass wenn mal ein Thread hängen bleibt (wenn nicht gerade in einer CriticalSection) das Programm noch weiter laufen kann und nicht plötzlich irgend welche Zugfahrten unüberwacht weiter laufen und es zu Unfällen kommt.
Mann kann auch einen Thread als "Endlosschleife" programmieren:
Falls ein Thread möglichst eigenständig arbeiten soll...
Ich würde auch zu den Threads greifen. Hat auch den Vorteil, dass wenn mal ein Thread hängen bleibt (wenn nicht gerade in einer CriticalSection) das Programm noch weiter laufen kann und nicht plötzlich irgend welche Zugfahrten unüberwacht weiter laufen und es zu Unfällen kommt.
Mann kann auch einen Thread als "Endlosschleife" programmieren:
Code: Alles auswählen
Procedure MyThread.Execute;
While not Self.Terminated do Begin
// Tue irgendwas
end;
end;
Falls ein Thread möglichst eigenständig arbeiten soll...