![]() |
Thumbnails via Threads laden
Hi,
ich möchte viele Thumbnail-Ladevorgänge in Threads auslagern. Wie könnte man das performant tun ? Ich dachte eine Zeit lang an eine Rekursion. Ein Thread arbeitet, wenn fertig wird der nächste erstellt, welcher wieder arbeitet. Dies würde so lange ablaufen, bis nichts mehr übrig ist. Es zu programmieren erschien mir allerdings unmöglich. Daher dachte ich an mehrere Threads welche mit Critical Sections gesichert sind. So wie ich das sehe bräuchte ich dann ein Array of TThumbnailThread (TThumbnailThread ist eine Ableitung von TThread). Brauche ich das wirklich ? Denn ich denke das wäre ab einer gewissen Anzahl von zu ladenden Thumbnails sehr belastend. Gibt es noch andere Lösungsmöglichkeiten ? |
Re: Thumbnails via Threads laden
Du solltest nicht viel mehr Threads erstellen als CPU-Kerne vorhanden sind (wobei Hyperthreading-Kerne mehrfach gezählt werden sollten, aber das ist nicht so wichtig). Sonst gibt es nämlich nur mehr Overhead.
Du könntest das Ganze gut mit einer Auftragsliste implementieren: Jedes zu bearbeitende Bild ist ein Auftrag. Wenn du die noch ausstehenden und beendeten Aufträge in einer Linked List speicherst, kommst du sogar ohne Critical Sections aus. |
Re: Thumbnails via Threads laden
Wäre es dann nicht schwierig die geladenen Bilder zurückzugeben ? Es soll nämlich nach jedem geladenen Bild dieses auch in der ListView erscheinen.
|
Re: Thumbnails via Threads laden
Das sollte kein riesiges Problem darstellen. TThread bietet die Möglichkeit, dem Hauptthread Arbeiten zuzuteilen, und zwar nicht blockierend wie bei Synchronize (Klassenmethode Queue). Da könntest du dann einfach immer ein Aktualisierungsroutine angeben. Am besten führst du einfach eine globale boolsche Variable ein: Sie hat den Status False, wenn die Routine gerade nicht in der Warteschlange steckt, ansonsten True. Am Anfang der Aktualisierungsmethode setzt du sie auf false und holst so viele Thumbnails wie möglich aus deiner Liste der fertigen Aufträge. Wenn ein Thread einen Auftrag bearbeitet hat, setzt er den Status der globalen Variable mit InterlockedExchange auf True und fügt, falls die Variable vorher den Wert False hatte, die Aktualisierungsroutine der Warteschlange hinzu.
Um das deutlich zu machen:
Delphi-Quellcode:
var GlobalFlag: Boolean;
procedure ThreadRoutine; var Job: TThumbnailJob; begin while DequeueJob(JobsToDo, Job) do begin Job.Execute; QueueJob(ExecutedJobs, Job); if InterlockedExchange(Integer(GlobalFlag), Integer(True)) = Integer(False) then TThread.Queue(nil, MyForm.UpdateListView); end; end; procedure TMyForm.UpdateListView; var Job: TThumbnailJob; begin GlobalFlag := false; while DequeueJob(ExecutedJobs, Job) do begin AddThumbnailToListView(Job); Job.Free; end; end; |
Re: Thumbnails via Threads laden
Wäre dann JobsToDo eine LinkedList ?
|
Re: Thumbnails via Threads laden
Das wäre das Effektivste. Du kannst natürlich auch eine TObjectQueue mit einer Critical Section oder was auch immer verwenden, aber der große Vorteil von verketteten Listen ist, dass du kein Synchronisations-Objekt benötigst. Allerdings ist die Implementierung nicht ganz trivial, du brauchst die Interlocked-Funktionen. Windows bietet aber entsprechende
![]() |
Re: Thumbnails via Threads laden
Ich frage mich gerade ganz ehrlich, was überhaupt wirklich eine LinkedList ist. Stehen nicht in der Liste dann die ganzen Thumbnails drinnen ? Damit es funktioniert muss ich allerdings einen eigenen Datentyp übergeben, weil sonst der Thread zu wenig Informationen besitzt um zu arbeiten. Dafür kann ich eigentlich nur ein Array of TDatentyp nehmen. Abgesehen davon gilt noch zu beachten, dass es nicht zu sehr auf der API basieren sollte. Daher habe ich extra TThread und nicht BeginThread genommen.
|
Re: Thumbnails via Threads laden
TThumbnailJob ist eine Klasse mit allen benötigten Informationen. Wenn du die API nicht verwenden willst und du nichts gegen ein kleines bisschen Overhead hast, kannst du auch einfach eine TThreadList nehmen.
|
Re: Thumbnails via Threads laden
Und in diese Liste kommen alle noch abzuarbeitenden Bilder rein ?
|
Re: Thumbnails via Threads laden
Ja. Du hast zwei Listen, eine für die fertigen Aufträge und eine für die noch ausstehenden. Jeder Auftrag wird durch eine Objektinstanz repräsentiert, die die Bilder, eventuell andere Einstellungen und das fertige Thumbnail (das ist natürlich nur in der Liste der fertigen Aufträge zugewiesen) enthält.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:25 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