![]() |
Wie Datenaustausch zwischen Thread und Hauptprogramm
Ich habe ein Programm geschrieben, wie im Hintergrund ein Thread Daten verarbeitet. Nun kommt es vor, dass das Programm ohne ersichtlichen Grund nach 1-2 Tagen abstürzt. Da ich im Forum nun einiges über Probleme mit Threads gelesen habe, vermute ich, dass es damit zu tun hat. Ich nutze schon Synchronize(), um einige visuelle Komponenten zu aktualisieren. Im Forum wird geschrieben, dass man die im Thread genutzen Daten nicht global deklarieren sollte, aber wie bekomme ich den Datenaustausch zwischen Thread und Hauptprogramm hin? Im Moment habe ich ein Array, in dem hauptsächlich der Thread schreibt, aber einige Sachen werden auch vom Hautpprogramm geschrieben und gelesen. Wenn ich das richtig gelesen habe, kann es dann nur vorkommen, dass beide Seiten auf die selbe Adresse zugreifen. Da sollte es aber bei meinem Programm nicht zum Komplettabbruch führen oder? Wenn das Programm auf normalem Wege beendet werden würde, hätte ich einen Eintrag im Logfile, aber das ist nicht der Fall.
Hat jemand ein Beispiel, wie man sicher Daten austauscht? Für ein Memo habe ich schon eine Lösung in der DP bekommen. |
Re: Wie Datenaustausch zwischen Thread und Hauptprogramm
Ist das Array dynamisch oder statisch?
statisch = Array[x..y] of irgendwas; dynamisch = Array of irgendwas; SetLength(dynamisch, y); Wird der Zugriff (Lesen UND Schreiben) vom Thread aus synchronisiert? Greifen Thread und Programm über die selbe Variable auf das Array zu und wäre es notfalls möglich, das Beide mit einer eigenen Array-Kopie arbeiten? |
Re: Wie Datenaustausch zwischen Thread und Hauptprogramm
Das Array ist statisch (Sess : array[0..maxSession-1] of TSess;)
Eigentlich laufen die ganzen Aktionen im Thread ab. Wenn ich das Programm einmal starte, dann macht das alles der Thread. Und da passiert es auch schon, dass sich das Programm von alleine "verabschiedet". Als einziges, was noch läuft im Hauptprogramm ist ein Sekundentimer, der im Array Werte abfragt, also nur liest. Könnte es vielleicht damit zusammenhängenn, dass ich außerhalb des Threads den Wert "SekFinihsed" setze und hier im Thread abfrage und zurücksetze?
Delphi-Quellcode:
procedure TMyThreads.Execute; begin repeat //ein Timer setzt jede Sekunde diesen Merker, so dass die Abarbeitung der Threadfunktion nur einmal pro Sekunde läuft //wenn der Thread in der Sekunde nicht fertig ist, dann ist es auch kein Problem if SekFinished then begin SekFinished:=False; //hier läuft der Thread end; Inc(ThrTmr); //hier nur ein Timer, damit ich sehen kann, wie schnell was läuft, dieser wird im Timer abgefragt und dann in die Statusleiste geschrieben if Terminated then break; Synchronize(UpdateCaption); until Terminated; end; |
Re: Wie Datenaustausch zwischen Thread und Hauptprogramm
Zitat:
Was ist denn alles in TSess drin (vorallem dynamische Arrays sowie Strings könnten noch Probleme machen) Und wie synchronisiertst du den Zugriff? |
Re: Wie Datenaustausch zwischen Thread und Hauptprogramm
Im Sess sind einige Strings, aber keine dynamischen Arrays. Des Weiteren noch einige Typen.
Delphi-Quellcode:
Synchronisiert habe ich bis jetzt gar nichts. Wenn es das Probleme geben sollte, müßte doch mein Programm irgendwelche Fehlberechnungen machen, aber es stürzt einfach ab, ohne irgendwelche Meldungen, nicht mal eine Windowsnachricht kommt.
TSess = record
inUse : Boolean; MaIdx : integer; Jobart : ESess; TimeOutValue : TDateTime; TimeOut : Boolean; ActFkt : ESessActFkt; Status : ESessStat; Stop : Boolean; //wenn Funktion durch Benutzer abgebrochen werden soll ErrCode : ESessErrCode; ErrTxt : string; fNameMain : string; ContentResponseFile : String; ContentLogFile : String; Aufgabe : EAufgabe; end; |
Re: Wie Datenaustausch zwischen Thread und Hauptprogramm
Zitat:
- kann es in seltenen Fällen vorkommen, dass der Timer erneut ausgelöst wird, während der Thread noch läuft (z.B. bei besonders hoher Rechneraktivität)? - kann es sein, dass Memoryleaks entstehen? Das lässt sich mit FastMM4 schnell herausfinden, und würde auch zu der langen Laufzeit (1 - 2 Tage) passen Cheers, |
Re: Wie Datenaustausch zwischen Thread und Hauptprogramm
Wenn der Timer schon wieder auslöst, sollte es doch eigentlich kein Problem sein. Es wird nur einfach der Merker gesetzt und wenn der Thread halt noch nicht dort vorbei ist, kommt er halt später vorbei. Aber manchmal gehen vielleicht Thread Programme eigene Wege.
Memoryleaks hatte ich noch, weil ein x.free fehlte. Das habe ich aber schon rausgefunden und nun läuft das Programm (soweit es denn läuft) ohne dass mehr Speicher beansprucht wird (laut Taskmanager). Wo ich den Fehler noch drin hatte, kamen alle paar Sekunden einige KB an Speicher hinzu. Ich habe jetzt mal ein Sleep(1000) mit in die Schleife gebaut, da das Programm ansonsten nicht rechenintensiv ist. Mal sehen, was rauskommt. Jedenfalls kommt das Problem auf verschiedenen Rechnern, nur Unterschied ist, dass es beim einen Rechner ca. 1/2 Tag dauert, beim anderen ca. 1,5 Tage. Hängt vielleicht vom Prozessor ab. |
Re: Wie Datenaustausch zwischen Thread und Hauptprogramm
Ich habe nochmal auf den Speicherverbrauch im Taskmanager geschaut. Nun läuft das Programm schon einen Tag und ist von 7864 KB abuf 8032 KB gestiegen. Ist das noch normal oder kann man hier auch schon von einem Speicherleak sprechen?
|
Re: Wie Datenaustausch zwischen Thread und Hauptprogramm
Zitat:
|
Re: Wie Datenaustausch zwischen Thread und Hauptprogramm
Seitdem ich x.free drin habe, ist es wirklich sehr wenig, was so über den Tag mehr wird. Bevor ich den Fehler behoben hatte, konnte man im Taskmanager zusehen, wie der Speicher mehr wurde.
Das Programm sollte schon eine Woche durchhalten, ohne dass das Programm neu gestartet wird. Jetzt ist ca. 1 Tag vorbei. Mal sehen, ob es noch einige Tage durchhält. Ich habe auch mal die Prio von tpIdle auf tpLower gesetzt, vielleicht stürzte das Programm ab, weil keine Rechenzeit mehr frei war??? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:11 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz