Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Wie Datenaustausch zwischen Thread und Hauptprogramm (https://www.delphipraxis.net/132733-wie-datenaustausch-zwischen-thread-und-hauptprogramm.html)

zeras 18. Apr 2009 13:06


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.

himitsu 18. Apr 2009 13:21

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?

zeras 18. Apr 2009 13:25

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;

himitsu 18. Apr 2009 13:29

Re: Wie Datenaustausch zwischen Thread und Hauptprogramm
 
Zitat:

Zitat von zeras
Das Array ist statisch

gut, dann gibt es schonmal kein Problem mit der Referenzzählung des Arrays selber :angel:

Was ist denn alles in TSess drin (vorallem dynamische Arrays sowie Strings könnten noch Probleme machen)

Und wie synchronisiertst du den Zugriff?

zeras 18. Apr 2009 13:40

Re: Wie Datenaustausch zwischen Thread und Hauptprogramm
 
Im Sess sind einige Strings, aber keine dynamischen Arrays. Des Weiteren noch einige Typen.

Delphi-Quellcode:
 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;
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.

mjustin 18. Apr 2009 15:24

Re: Wie Datenaustausch zwischen Thread und Hauptprogramm
 
Zitat:

Zitat von zeras
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.

Zwei Vermutungen habe ich:

- 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,

zeras 18. Apr 2009 15:36

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.

zeras 19. Apr 2009 16:08

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?

mjustin 19. Apr 2009 17:27

Re: Wie Datenaustausch zwischen Thread und Hauptprogramm
 
Zitat:

Zitat von zeras
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?

Mit x.free oder ohne? Wenn das gefixte Leck die Fehlerursache war, wird das Programm nun ja nicht mehr so schnell abstürzen. Wenn aber bei nur 8 MB Speicherbedarf das Programm abstürzt, sieht es eigentlich nicht nach Speicherleck aus.

zeras 19. Apr 2009 17:43

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 14:47 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz