AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Rechenintensiven Thread aufräumen

Ein Thema von Schwedenbitter · begonnen am 9. Nov 2014 · letzter Beitrag vom 11. Nov 2014
Antwort Antwort
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#1

AW: Rechenintensiven Thread aufräumen

  Alt 9. Nov 2014, 12:11
Ich würde es bei den Speicherlecks lassen - Windows räumt ja auf. Aber wenn es dir so wichtig ist:

Komprimiere nur einen kleinen Teil des Bilds und nehme dies als Anhaltspunkt, welches Format besser ist
Schreibe den JPG/PNG Algorithmus selbst oder binde eine Bibliothek ein, die das unterbrechen gestattet.
Entwickle eine Heuristik. Zum Beispiel sind Bilder mit Gradienten und homogenen Flächen tendenziell besser für PNG geeignet, Bilder mit vielen Details besser für JPG.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.556 Beiträge
 
Delphi 12 Athens
 
#2

AW: Rechenintensiven Thread aufräumen

  Alt 9. Nov 2014, 13:14
Wie wäre es, wenn man auf das Ende der Threads wartet, bevor sich die Anwendung beendet?
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#3

AW: Rechenintensiven Thread aufräumen

  Alt 9. Nov 2014, 14:29
Wie wäre es, wenn man auf das Ende der Threads wartet, bevor sich die Anwendung beendet?
So mache ich es im Moment. Aber das Komprimieren je einer JPEG und einer PNG-Datei kann bei einem 200 dpi Bild mit durchschnittlicher CPU mal eben jeweils 8 Sekunden dauern. Bei 10 Bildern will man nicht wirklich warten. Mir wäre es auch egal, weil der Benutzer die Speicherlecks nicht sieht. Aber es ist unsaubere Programmierung.
Alex Winzer
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.556 Beiträge
 
Delphi 12 Athens
 
#4

AW: Rechenintensiven Thread aufräumen

  Alt 9. Nov 2014, 14:53
  • die Thread-Instanz darf sich nicht selber freigeben
  • das Programm ruft Thread.Terminate auf
  • die Threads beenden sich (nach durchschnittlich 4 Sekunden aka 50% von 8 Sekunden)
  • das Programm wartet auf das Ende
  • und beendet sich dann
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#5

AW: Rechenintensiven Thread aufräumen

  Alt 9. Nov 2014, 15:01
Aber das Komprimieren je einer JPEG und einer PNG-Datei kann bei einem 200 dpi Bild mit durchschnittlicher CPU mal eben jeweils 8 Sekunden dauern.
Nochmal: Du schmeißt 8 Sekunden Arbeitszeit einfach weg, wenn du die Größe hast

Bei 10 Bildern will man nicht wirklich warten.
Eventuell könnte dir ein Threadpool gut tun. Wenn die 10 Threads nebenläufig rödeln, kommen die sich vermutlich bloß in die Quere.
Außerdem könntest du im Threadpool vor dem Vergeben einer neuen Aufgabe prüfen, ob die Anwendung beendet wurde.

An deiner Stelle würde ich mir tatsächlich eine TStream-Ableitung schreiben und mal gucken, wie die Bibliotheken den Stream benutzen. Wenn die regelmäßig Schreibzugriffe auf den Stream machen, dann wäre das eine schöne Gelegenheit, den ganzen Quark mit einer Exception (oÄ.) abzubrechen.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6

AW: Rechenintensiven Thread aufräumen

  Alt 10. Nov 2014, 00:28
Wenn ein Prozess beendet wird, egal wie, ob regulär oder wenn über den Taskmanager, gibt es keine Speicherlecks. Wo sollen die auch sein? Speicherlecks kann es nur innerhalb eines Prozesses geben. Dieser existiert aber nicht mehr. Man kann ja auch kein Loch in einem Loch buddeln. Des weiteren schließt Windows automatisch alle von dem Prozess geöffneten Händels. Also: Prozess beendet, alles gut.

Natürlich kann man darüber diskutieren, ob es guter Programmierstil ist nicht hinter sich aufzuräumen. Da hat jeder seine eigene Meinung.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.556 Beiträge
 
Delphi 12 Athens
 
#7

AW: Rechenintensiven Thread aufräumen

  Alt 10. Nov 2014, 08:45
Wenn man selber aufräumt, dann sieht man zumindestens, ob sich unbeabsichte Löcher verstecken.
Und wenn richtig aufgeräumt wird, dann sind Fehler beim Beenden minimiert.

z.B. Komponente auf Form, die beim Beenden auf etwas Globales in einer Unit zugreift ... wenn die Unit bereits ordentlich entladen wurde, dann würde es durt womöglich schön knallen.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Rechenintensiven Thread aufräumen

  Alt 10. Nov 2014, 11:08
Die Spiecherlecks werdn doch deshalb angezeigt, weil die Threads beim Beenden des Prozesses einfach abgeschossen werden und die von jedem Thread belegten Ressourcen nicht freigeben wurden.

Wenn man das nicht haben möchte, dann muss man sich eben selber um die Freigabe der Threads kümmern und nicht TThread.FreeOnTerminate := True; wegdelegieren.

BTW: Das hier ist grober Unfug:
Delphi-Quellcode:
Constructor TCalcThread.Create(Codec: TCodecType; Bitmap: TBitmap;
   OnCalcDone: TOnCalcDone);
Begin
   fSize:= -1; // ungültigen Wert vorgeben
   fCodec:= Codec; // Codec merken
   fOnCalcDone:=OnCalcDone; // Zeiger auf Ereignis merken
   fBitmap:=TBitmap.Create; // TBitmap anlegen
   fBitmap.Assign(Bitmap); // Bild kopieren
   FreeOnTerminate:=True; // Speicher selbst freigeben

   Inherited Create(True); // Thread erstellen
   Priority:= tpIdle; // geringe Priorität
// Resume; // "Start" löst Exception aus!
   Start; // "Resume" ist veraltet
End;
Während der Constructor abgearbeitet wird wird der Thread nicht loslaufen! Mit der Erkenntnis kann der Code wie folgt geschreiben werden:
Delphi-Quellcode:
Constructor TCalcThread.Create(Codec: TCodecType; Bitmap: TBitmap;
   OnCalcDone: TOnCalcDone);
Begin
   fSize := -1; // ungültigen Wert vorgeben
   fCodec := Codec; // Codec merken
   fOnCalcDone := OnCalcDone; // Zeiger auf Ereignis merken
   fBitmap := TBitmap.Create; // TBitmap anlegen
   fBitmap.Assign( Bitmap ); // Bild kopieren

   Inherited Create( False ); // Thread erstellen
   Priority := tpIdle; // geringe Priorität
   FreeOnTerminate := True; // Instanz selbst freigeben <- hmmm, nicht geschickt
End;
Der Destructor sollte allerdings wie folgt aufgebaut werden:
Delphi-Quellcode:
Destructor TCalcThread.Destroy;
Begin
   fOnCalcDone:=nil; // Zeiger löschen

   Inherited; // den Rest ausführen

   fBitmap.Free; // TBitmap selbst freigeben
End;
In TThread.Destroy wird unter anderem TThread.Terminate aufgerufen, weil der Thread ja noch aktiv sein kann. Wenn man dem Thread während der Abarbeitung die Ressource fBitmap unter dem A.... wegzieht, was kann dann passieren? Genau, es knallt. Also erst inherited , danach ist der Thread gesichert beendet und dann können alle Ressourcen ohne Reue freigeben werden!
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:49 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