[gelöst] Sleep - Ungewohntes Verhalten?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: [gelöst] Sleep - Ungewohntes Verhalten?

Beitrag von m.fuchs »

Nein, dein Timer ist nicht kaputt, du stößt nur auf die Grenzen des Systems. Ein Intervall von 10000 bedeutet nicht dass der Timer tatsächlich alle 10 Sekunden. Es kann auch mal länger dauern, je nachdem was das System grad zu tun hat.

Ich habe dein Szenario hier mal nachgestellt und habe tatsächlich alle zehn Sekunden eine Ausführung von OnTimer gesehen. Auch wenn diese Ausführung selber fünf Sekunden dauerte.
Ich bin mir nicht sicher, aber es kann auch noch von OS zu OS unterschiedlich sein.

Wenn du es wirklich genau brauchst gibt es zwei Fasutregeln:

Es muss mindestens die Zeit X zwischen zwei Timer-Events vergehen. Egal wie lange die Ausführung des Events dauert.
In diesem Fall mach es so wie von mir oben beschrieben. Am Anfang von OnTimer den Timer abschalten, am Ende wieder anschalten.

Es soll alle X Zeitintervalle etwas ausgeführt werden.
Setz den Timer auf ein kürzeres Intervall (zum Beispiel X/10). Merk dir einen Startzeitpunkt. prüfe bei jedem Aufruf des Intervalls ob schon Startzeitpunkt + X erreicht wurde. Setze den Startzeitpunkt auf die aktuelle Zeit und führe dann deinen Code aus.
Wenn die Ausführung des Code länger dauert, sollte er in einen Thread ausgelagert werden. Je nachdem wie genau es sein muss, muss du den Teiler für X wählen.

Und selbst wenn du das alles berücksichtigst, muss das Ergebnis nicht genau sein.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

Re: [gelöst] Sleep - Ungewohntes Verhalten?

Beitrag von Erwin »

m.fuchs, inzwischen habe ich die wirkliche Ursache gefunden, durch vieles hin und her austesten.

Habe jetzt alles (sleep und Timer) mit Lazarus unter Windwos getestet. Da liegen traurigerweise kleine Unterschiede vor. Also wenn man etwas mit Timer und/oder sleep schreibt, ist es mit einfachen compilieren unter anderem System nicht getan, sondern muss noch mal getestet und eventuell nachgebessert (eher dann umgeschrieben) werden.

sleep: Unter Win funktioniert es so, wie ich es Anfangs erwartet habe: Das ganze wird angehalten, und danach geht es weiter. Wenn es innerhalb eine Schleife ist, wird das derzeit aktuelle Zwischen-Ergebnis, wie angefordert, auch ausgegeben (ohne dem extra Befehl ProcessMessages), und nicht erst wenn er mit allem Fertig ist. Finde es schade, dass unter Linux dies nicht der Fall ist. Nicht unbedingt das mit dem Sleep, sondern dass obwohl in der Schleife man das aktuelle Zwischenergebnis auf dem Caption sehen will, dies dennoch nicht geschieht, ohne Extra Befehl, der auch noch dann alles verlangsamt.
Na toll, mir fällt ein, dass ich etwas vergessen habe zu testen: Ob unter Windows die Schleifen länger dauern, weil auch die Angeforderten Zwischenergebnisse angezeigt werden? Anderseits kann man dies schwer wirklich vergleichen, denk ich. Aber wenn dem so wäre, wäre dies vielleicht ein Grund, wieso es bei Linux anders ist. (Wegen mehr Geschwindigkeit?). Aber anderseits, wenn an es sehen will, sollte man dies zulassen, finde ich.

Timer: Dort wird ebenfalls unter Windows beim abarbeiten einer Schleife, in der man das aktuelle Zwischenergebnis auf einen Caption sehen will, angezeigt.
Unter Linux muss man leider den uns bereits längst bekannten Befehl 'Application.ProcessMessages' dazu bemühen. Dieser verlangsamt das Ganze nicht nur enorm, sondern sorgt scheinbar gleichzeitig auch dafür, dass die bereits abgelaufene Zeit des Timer wieder auf Anfang gestellt wird. Ohne den Befehl fängt es auch bei mir alle 10 Sekunden von neu an, anstatt 10+Arbeitszeit (mit dem Befehl).
Des weiteren stellte ich fest, das wenn ein Timer was zu tun hat, andere Timer anhält. Es sei denn, der Timer, der dann viel zu tun hat, hat halt im Arbeitsgang den Befehl 'Application.ProcessMessages' drin, mit all seinen anderen negativ-Folgen (langsamere Verarbeitung, neu Start der Timerablaufzeit).

Und will man, während der Timer an etwas Längerem arbeitet, selber was machen können (Button drücken), kommt man um den Application.ProcessMessages nicht darum herum. Das war mir teils auch neu. Wenn der Timer was ausführt, gehen keine Buttons etc., sondern erst nach dessen Arbeit wird die Buttoneingabe abgearbeitet. Das würde erklären, wieso bei den Arcaden-Spielen oft dann, wenn besonders viel Bewegung im Bildschirm vorhanden war, die Tasten oft verzögert reagiert haben?

Also ich finde, da hätte in den Bücher viel mehr zum Timer geschrieben gehört. Stattdessen musste ich es selber herausfinden. Und ich finde, das sind teils Versteckte Fallen, weil man erst am einen bestimmten Punkt merkt, dass 'was' nicht Stimmt. Und nicht selten sucht man dann an falscher Stelle. Stattdessen las sich zum Timer meist eher so, als wäre es egal, was dieser macht, der ganze Ablauf ginge wie gewohnt weiter. Was aber eben nicht der Fall ist.

All diese Erkenntnis finde ich ernüchtern. Besonders dann, wenn man vielleicht mal eine Arcade-Spiel programmieren will.
Lazarus 2.2.0 / FP 3.2.4

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: [gelöst] Sleep - Ungewohntes Verhalten?

Beitrag von Mathias »

Das Problem hatte ich auch schon, das eine Animation unter Linux und Win unterschiedlich läuft.
Unter Win ist ein Timerintervall, bei ca. 40 Schluss. Unter Linux geht es auch kleiner.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: [gelöst] Sleep - Ungewohntes Verhalten?

Beitrag von mschnell »

Erwin hat geschrieben:m.fuchs, inzwischen habe ich die wirkliche Ursache gefunden, durch vieles hin und her austesten....

Wenn man versucht an der von der LCL realisierten Programm-Struktur (nennt sich "Ereignis-Orientiertes Programmieren" vorbei-zuarbeiten, darf man sich nicht wundern, wenn nichts so funktioniert, wie man es erwartet.

Dafür kann man auch keinen sinnvollen Support aus der community erwarten.

Wenn Du eine andere Programm-Struktur realisieren willst, erzeuge in der IDE keine "Application" sondern ein "command line tool".

-Michael

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: [gelöst] Sleep - Ungewohntes Verhalten?

Beitrag von m.fuchs »

Erwin hat geschrieben:m.fuchs, inzwischen habe ich die wirkliche Ursache gefunden,

Das bezweifele ich, ehrlich gesagt.

Erwin hat geschrieben:Also wenn man etwas mit Timer und/oder sleep schreibt, ist es mit einfachen compilieren unter anderem System nicht getan,

Vor allen Dingen sollte man nicht mit falschen Erwartungen an die Sache herangehen.

Erwin hat geschrieben:sleep: Unter Win funktioniert es so, wie ich es Anfangs erwartet habe: Das ganze wird angehalten, und danach geht es weiter. Wenn es innerhalb eine Schleife ist, wird das derzeit aktuelle Zwischen-Ergebnis, wie angefordert, auch ausgegeben (ohne dem extra Befehl ProcessMessages), und nicht erst wenn er mit allem Fertig ist.

Kann sein, muss aber nicht. Auf alle Fälle werden keine weiteren Messages abgearbeitet in der Zeit. Klickt der User also irgendwo hin, dann kommt dieser Klick erst nach Ablauf deiner Schleife an.
Deswegen: Bei langen Laufzeiten immer Application.ProcessMessages benutzen!

Erwin hat geschrieben:Finde es schade, dass unter Linux dies nicht der Fall ist. Nicht unbedingt das mit dem Sleep, sondern dass obwohl in der Schleife man das aktuelle Zwischenergebnis auf dem Caption sehen will, dies dennoch nicht geschieht, ohne Extra Befehl, der auch noch dann alles verlangsamt.

Wie gesagt, auch unter Windows ist das notwendig. So funktionieren nämlich diese Ereignis-basierten Fenstersysteme.

Erwin hat geschrieben:Timer: Dort wird ebenfalls unter Windows beim abarbeiten einer Schleife, in der man das aktuelle Zwischenergebnis auf einen Caption sehen will, angezeigt.

Du hast eine Schleife innerhalb deiner OnTimer-Methode? Das ist doch dann wirklich absurd.

Erwin hat geschrieben:Unter Linux muss man leider den uns bereits längst bekannten Befehl 'Application.ProcessMessages' dazu bemühen.

Noch einmal: Wenn dein Programm während einer Aufgabe auf Messages reagieren soll, sei es für Anzeige oder Klicks, musst du Application.ProcessMessages nutzen. Egal unter welchem System.

Erwin hat geschrieben:Des weiteren stellte ich fest, das wenn ein Timer was zu tun hat, andere Timer anhält. Es sei denn, der Timer, der dann viel zu tun hat, hat halt im Arbeitsgang den Befehl 'Application.ProcessMessages' drin,

Was daran liegt, dass auch die Timer mit Hilfe von Messages realisiert werden. Kommen keine an, dann funktioniert das auch nicht.

Erwin hat geschrieben:Also ich finde, da hätte in den Bücher viel mehr zum Timer geschrieben gehört. Stattdessen musste ich es selber herausfinden.

Ja das mag sein. Und es wird noch komplizierter, wenn man noch Threads einsetzt. Dafür kann man damit dann auch wirklich parallel arbeiten.

Was ist eigentlich dein tatsächliches Problem? Dann kann man auch eine passende Lösung vorschlagen.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: [gelöst] Sleep - Ungewohntes Verhalten?

Beitrag von Michl »

m.fuchs hat geschrieben:Bei langen Laufzeiten immer Application.ProcessMessages benutzen!
Ich muss hier mal einhaken. Bei einem kleinen Programm kann man das sicherlich so machen. Bei richtigen Anwendungen würde ich nicht so verfahren. Application.ProcessMessages ist kein Allheilmittel, sondern mMn eher ein Zeichen schlechten Codes. Falsch eingesetzt (im falschen Event), kann es zu Mehrfachzeichnen bzw. Endlosloops kommen, da dann manchmal die Systemmessages nicht ordentlich abgearbeitet werden können. IIRC, nutze ich dies überhaupt nicht. Wenn es gar nicht anders geht, manchmal AsyncCall.

@Erwin:
Eine GUI ist meiner Meinung nach hauptsächlich dafür gedacht, eine Kommunikation Mensch <-> Maschine zu ermöglichen (Einlesen von Userinputs, Ausgabe Information an den User etc.). Wenn ein Programm einfriert (und ist es nur für eine Sekunde), ist das für den User unangenehm (evtl. klickt er dann mehrfach auf einen Butten, tippt mehrfach Zeichen etc.). Ein Sleep gehört nicht in die Mainqueue. Zeitaufwendige Berechnungen, die ein Einfrieren der Anwendung verursachen, gehören, wenn möglich, in einen Workerthread.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: [gelöst] Sleep - Ungewohntes Verhalten?

Beitrag von mschnell »

Michl hat geschrieben:ProcessMessages ist kein Allheilmittel, sondern mMn eher ein Zeichen schlechten Codes.


Naja.- Wenn man z.B. die ersten 1000 Dezimalstellen von Pi ausrechnen will kann es schon nützlich sein, um einen Fortschrittsbalken anzuzeigen und da Programm abbrechen zu können.

-Michael

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: [gelöst] Sleep - Ungewohntes Verhalten?

Beitrag von Mathias »

Wenn man z.B. die ersten 1000 Dezimalstellen von Pi ausrechnen will kann es schon nützlich sein, um einen Fortschrittsbalken anzuzeigen und da Programm abbrechen zu können.


Hier sieht man, das solche Sachen gar nicht so einfach sind: viewtopic.php?f=18&t=11564
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: [gelöst] Sleep - Ungewohntes Verhalten?

Beitrag von m.fuchs »

Michl hat geschrieben:
m.fuchs hat geschrieben:Bei langen Laufzeiten immer Application.ProcessMessages benutzen!
Ich muss hier mal einhaken. Bei einem kleinen Programm kann man das sicherlich so machen. Bei richtigen Anwendungen würde ich nicht so verfahren. Application.ProcessMessages ist kein Allheilmittel, sondern mMn eher ein Zeichen schlechten Codes.

Naja, so weit würde ich jetzt nicht gehen. Aber du hast schon recht, ein Allheilmittel ist es wirklich nicht. Gerade wenn es um längere Abarbeitung geht und man dort vielleicht nicht einmal unterbrechen kann um die Messages bearbeiten zu lassen, kommt man kaum um Threads herum.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

Re: [gelöst] Sleep - Ungewohntes Verhalten?

Beitrag von Erwin »

Nun ich habe es nicht genau ausgedrückt, dass man mit Application.ProcessMessages auch unter Win nichts mehr machen kann, aber als ich das erwähnte, meinte ich damit beide BS. Da habe ich leider vergessen, es genauer zu erwähnen.

Der Unterschied ist halt vermutlich, unter Linxu ist es schneller, während man unter Win sehen kann, dass sich was tut. Unter Wind wird es aber vermutlich länger dauern. Denn die Darstellung der Zahl (ohne Application.ProcessMessages, sondern allein durch 'Caption:=IntToStr(I)' in der Schleife) kostet sicherlich ebenfalls Zeit , als wenn die Schleife ohne dessen Ausgabe abgearbeitet würde. Sollt es mal zur langen Schleife kommen, mag das Endresultat zwar das gleiche sein: Man ist über das BS/Prorgramm verärgert. Der Grund aber ein Anderer: Der eine (unter LInux) weil es 'eingefroren' ist, der User unter Win, weil die Schleife verdammt lange dauert. Jeder hat halt andere Vorlieben. Was besser ist, obwohl ich es lieber mag, zu sehen, wenn es noch was tut (und somit also nicht eingefroren sein kann), kann ich dennoch nicht sagen. Weil irgendwann dauert es auch mir die bestangezeite Schleife einfach zu lange.

Warum es mir geht, bzw. warum ich noch weiter geschrieben habe? Also inzwischen sind viele meine Fragen und mehr Beantwortet. Aber da ich durch Probieren vieles herausgefunden habe, was im Forum nicht steht, habe ich es hier rein geschrieben. Weil dann wird der Nächste, der sich hierher 'verirrt' ( (noch) die Suche nutzt), möglichst viele Infos dazu in einem Thread erhalten, denk ich.

Ich selber habe Heute nach etwas gesucht, und 3 Thread mit Bruchteil zu dem Ganzen gefunden. Hinzu kam, dass diese 3 diesmal zusammen leider kein Ganzes ergeben, weil jeder die Problemlösung anders angeht. Da wird, finde ich, am falschen Ende gespart. Weil mir hilft es nicht weiter. Da tippt man all dies ab, und muss dann feststellen, es fehlen x-code-zeilen. Also muss man dann Fragen. Und oebendrein vergeht einem nach und nach das Suchen, sondern gewöhnt sich dann an, generell zuerst zu fragen.
Und je mehr man über solche Beiträge stolpert, wo der Threadersteller einerseits um das gleiche Problem geht, aber dessen Beantwortung nur halb umschrieben ist ... also jedenfalls ist man/ich dann über all das Enttäuscht.
Lazarus 2.2.0 / FP 3.2.4

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: [gelöst] Sleep - Ungewohntes Verhalten?

Beitrag von m.fuchs »

Erwin hat geschrieben:Der Unterschied ist halt vermutlich, unter Linxu ist es schneller, während man unter Win sehen kann, dass sich was tut.

Ich sage es noch einmal, aber jetzt wirklich zum letzten Mal: Dass du unter Windows ohne ProcessMessages eine Ausgabe siehst ist schön, aber es gibt keine Garantie dafür.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: [gelöst] Sleep - Ungewohntes Verhalten?

Beitrag von mschnell »

Erwin hat geschrieben: also jedenfalls ist man/ich dann über all das Enttäuscht.

Es wurde mehrfach deutlich erklärt dass und warum das was Du da machst nicht zulässig ist in dem Sinne, dass das Ergebnis nicht Deinen Erwartungen entsprechen wird.
Wenn Du diese Hinweise konsequent ignorierst, ist Dir einfach nicht zu helfen.

Bitte poste erst dann wieder, wenn Du Dich über das Thema "Ereignisorientierte Programmierung" ("event driven programming") informiert hast.

Für konkrete Fragen dazu stehen wir gerne zur Verfügung.

-Michael

Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

Re: [gelöst] Sleep - Ungewohntes Verhalten?

Beitrag von Erwin »

@ mschnell
Du hast da was gewaltig durcheinander gebracht.
Es steht in der Überschrift gelöst dort, und das ist es auch: Gelöst.
Es tauchte die Frage auf, warum ich noch weiter schreibe. Dies habe ich beantwortet: Weil ich durch Test mehr erfahren habe, und nicht will, dass wenn Jemand durch Suche zu den Thread kommt, dann nur Teilweise Informationen erhält, wo ich bereits mehre dazu inzwischen habe, und mitteilen kann.
Der letzte Absatz bezieht sich auf die Erfahrung, die ich fast immer mache, und hat gar nichts mit der Sleep oder Timer-Sache zu tun. Ich habe gestern nach was gesucht (das nichts mit sleep oder Timer zu tun hatt). Fand 3 Threads, wo die Ersteller gleiches Problem wie ich hatte, aber ein Teil bereits wussten (?), und ihnen nur der andere Teil geantwortet wurde. Und in jedem wird das Problem anders angegangen, und ihn jedem fehlt einfach ein Teil. Bei mir klappt jedenfalls keiner der Abgeschrieben Code-Beispiele. Die Folge: Abtippen für nichts, suche für nichts. Dadurch frage mich auch, fehlt da tatsächlich noch was,oder ist einfach die Antwort falsch? Bringt es überhaupt was zu fragen, oder bekomme ich eh wieder die bereits mir bekannte falsche(?) Antwort? All das will ich demjenigen wenigen, die noch die Suche nutzen und dadurch über meinen Thread stolpern könnten, so weit es mir möglich ist, ersparen.
Schade dass scheinbar dafür kein Verständnis hast? Aber da weiß zumindest woran ich bin. Also in Zukunft nicht mehr suchen, sondern sofort fragen? Und auch nicht wundern, wenn man den notwendigen Gesamtcode dem Helfer nach und nach aus der Nase ziehen muss?
Und selber, wenn man mal was weiß, also auch nur das nötigste Antworten, selbst dann, wenn man davon ausgehen könnte, dass eine Codezeile allein nicht reichen wird?
Und ja, ich bin verärgert. Über 25 Threads (habe nicht nur hier gesucht, hier waren es ungefähr 5) zu meinem Thema, aber in dem meisten nur 1-2 lose Codezeilen oder Antworten, und nur 4-5 mit leider nur bis zur Hälfte erklärten Text und Code. Und viel Stunden suche. Das alles nervt eben.
Lazarus 2.2.0 / FP 3.2.4

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: [gelöst] Sleep - Ungewohntes Verhalten?

Beitrag von mschnell »

Und wieder hast Du den Hinweis auf "Ereignisorientierte Programmierung" ignoriert ...
-Michael

Antworten