Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi [Thread] Deadlock verhindern (https://www.delphipraxis.net/31136-%5Bthread%5D-deadlock-verhindern.html)

sieppl 4. Okt 2004 21:28


[Thread] Deadlock verhindern
 
Hi!

Mit diesem Code setze ich einen Thread auf suspended:

Delphi-Quellcode:
procedure TImgStdListView.SuspendThread;
begin
  if FThumbnailThread.Suspended then
    Exit
  else
  begin
    FThumbnailThread.RefreshNow(nil);
    while not FThumbnailThread.Suspended do
      Delay(300);
  end;
end;
Nun treten sporadisch ab und zu Deadlocks auf. Der ThumbnailThread hat an 2 oder 3 Stellen Synchronize-Aufrufe. Ich vermute der Deadlock tritt auf, wenn der Thread gerade Synchonize(Main-Methode) ausführt, die main-Methode aber auf suspended wartet. Zumindest kreise ich in der Delay-Schleife wenn mal wieder nichts geht. Gibt es da spezielle Techniken wie man an das Problem herangehen kann?

Grüße

Sebastian

fiasko 5. Okt 2004 09:33

Re: [Thread] Deadlock verhindern
 
Hallo,

normalerweise würde man sowas mit dem Konzept des gegenseitiger Ausschlusses machen - das dürfte aber hier nicht funktionieren durch die Architektur des "VCL-Threads". Warum mußt du denn warten bis der Thread wirklich suspended ist?

Du könntest probieren ein Application.ProcessMessages in die Schleife einzubauen, allerdings ist das nicht die feine Art mit einem Delay - denn da blockierst du auch die Oberfläche deines Programmes (kein Neuzeichnen etc.).

sieppl 5. Okt 2004 09:43

Re: [Thread] Deadlock verhindern
 
Zitat:

Zitat von fiasko
Hallo,

normalerweise würde man sowas mit dem Konzept des gegenseitiger Ausschlusses machen - das dürfte aber hier nicht funktionieren durch die Architektur des "VCL-Threads". Warum mußt du denn warten bis der Thread wirklich suspended ist?

Du könntest probieren ein Application.ProcessMessages in die Schleife einzubauen, allerdings ist das nicht die feine Art mit einem Delay - denn da blockierst du auch die Oberfläche deines Programmes (kein Neuzeichnen etc.).

Hi!

Ich muss warte, da der Thread Thumbnails generiert und dabei natürlich auf das Dateisystem zugreift. Viele Änderungen und Aktionen des Users erzeugen dann natürlich Zugriffsverletzungen, wenn der Thread nicht eingeschläfert wird, wenn er gerade generiert.
Der Delay ist wirklich nicht optimal. Man bräuchte einen Befehl der die Rechenzeit an die Threads abgibt. Hast du eine Idee?

fiasko 5. Okt 2004 09:50

Re: [Thread] Deadlock verhindern
 
Hallo,

na dann brauchst du aber auch keinen extra Thread. Wozu Nebenläufigkeit wenn der eine Thread die ganze Zeit delayed ist :mrgreen:

Ich weiß ja nicht genau wie dein Programm arbeitet, kann ich mir das so vorstellen das du eine Übersicht hast wofür die ganzen Thumbnails generiert werden? Dann würde ich die Thumbnails im Formular alle auf nil (oder irgendwie deaktiviert) setzen und der Thread ruft dann eine Callback-Funktion auf die Thumbnail für Thumbnail auf einen Bild setzt und das neuzeichnen veranläßt. Solange ein Thumbnail noch nil ist kann es halt nicht gezeichnet werden.

sieppl 5. Okt 2004 10:04

Re: [Thread] Deadlock verhindern
 
Zitat:

Zitat von fiasko
Hallo,

na dann brauchst du aber auch keinen extra Thread. Wozu Nebenläufigkeit wenn der eine Thread die ganze Zeit delayed ist :mrgreen:

Welchen Thread meinst du jetzt? Ich habe einen, der auf signaled eines FindNextNotification-Handles wartet und einen anderen der im Hintergrund die Thumbs generiert.

Zitat:

Ich weiß ja nicht genau wie dein Programm arbeitet, kann ich mir das so vorstellen das du eine Übersicht hast wofür die ganzen Thumbnails generiert werden? Dann würde ich die Thumbnails im Formular alle auf nil (oder irgendwie deaktiviert) setzen und der Thread ruft dann eine Callback-Funktion auf die Thumbnail für Thumbnail auf einen Bild setzt und das neuzeichnen veranläßt. Solange ein Thumbnail noch nil ist kann es halt nicht gezeichnet werden.
Also, der User klickt im TreeView einen Ordner an. Der ThumbThread wird aufgeweckt, der ListView (mit TImageList) wird mit einem Dummy-Bild bestückt. Es sollen nämlich zunächst ganz schnell alle Dateien angezeigt werden. Danach geht der Thread ein 2. Mal durch und ersetzt das DummyBild durch das Gerenderte. Falls der Thread unterbrochen wird, setzt er später seine Arbeit dort fort wo er auch aufgehört hat. Das sieht gut aus und läut auch. Der Thread hat die Prio tpLowest, der Notification-Thread tpLower.

fiasko 5. Okt 2004 10:12

Re: [Thread] Deadlock verhindern
 
Zitat:

Zitat von sieppl
Also, der User klickt im TreeView einen Ordner an. Der ThumbThread wird aufgeweckt, der ListView (mit TImageList) wird mit einem Dummy-Bild bestückt. Es sollen nämlich zunächst ganz schnell alle Dateien angezeigt werden. Danach geht der Thread ein 2. Mal durch und ersetzt das DummyBild durch das Gerenderte. Falls der Thread unterbrochen wird, setzt er später seine Arbeit dort fort wo er auch aufgehört hat. Das sieht gut aus und läut auch. Der Thread hat die Prio tpLowest, der Notification-Thread tpLower.

Genau so hab ich mir das vorgestellt. Ich hab das mit dem Suspend nurnoch nicht ganz verstanden - wann wird denn die Funktion suspendthread aufgerufen? Ich schätze mal wenn der Nutzer auf eine anderes Verzeichnis klickt und da sich die TImageList dann ändert fährt er in die Ecke?! Hmm, muß ich mal drüber nachdenken...

sieppl 5. Okt 2004 10:18

Re: [Thread] Deadlock verhindern
 
Ja genau, an einigen Stellen wird der Thread suspended. Zum Beispiel wenn Dateien in den gerade angezeigten Ordner kopiert/gelöscht/verschoben werden, Drag&Drop usw.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:31 Uhr.

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