![]() |
Rückgabewert von Threads
Guten Abend,
in einem Programm lasse ich anfallende rechenintensive Arbeit von mehreren Threads parallel erledigen. Neue Aufgaben sollen erst wieder verteilt werden, wenn alle Threads fertig gerechnet haben und alle Ergebnisse im Hauptprogramm abgelegt worden sind. Und genau bei letzterem fehlen mir noch brauchbare / elegante Ideen. Z.B. könnte ich mittels OnTerminate nach Beendigung der Berechnung eines Threads und VOR Freigabe des Threads eine Methode ausführen, jedoch sehe ich hier das Problem, dass diese Methode nicht weiß, welcher Thread gerade fertig geworden ist (dann könnte sie über eine simple Get-Funktion die Rückgabewerte holen und ins Hauptprogramm bringen). Gibt es da etwa Elegantes oder bin ich da unter Schönheitsaspekten auf dem Holzweg? Liebe Grüße Hannes |
AW: Rückgabewert von Threads
Zitat:
Oder du verwendest pro Thread-Instanz eine andere Event-Methode. |
AW: Rückgabewert von Threads
Lieber Herr Raabe,
vielen Dank für Ihre Ideen; die helfen mir weiter. Da habe ich wohl den Wald vor lauter Bäumen nicht gesehen :wink:! Einen schönen Abend noch Hannes |
AW: Rückgabewert von Threads
Hallo zusammen,
kaum hatte ich mir gestern Abend die Ideen von Betrag #2 zu Herzen genommen, ergab sich postwendend ein zweites Problem in diesem Kontext. In einer Schleife
Delphi-Quellcode:
erzeuge ich bei jedem Durchlauf einen Thread (mithilfe der Klasse TThread), sofern die maximale Anzahl nicht überschritten wird (hier: 4). Diese erhalten, wie eingangs erwähnt, ihre Aufträge übermittelt und beginnen unverzüglich mit der Berechnung.
for i := 0 to iBloecke - 1
Sofern alle "Slots" belegt sind, sprich max. Anzahl an Threads erreicht ist, müsste das Hauptprogramm logischerweise in der Schleife warten, bis die Threads wieder geschlossen sind. Im OnTerminate lasse ich mir vorher die Ergebnisse sichern.
Ich hoffe doch inständig, dass ihr mir da etwas Licht ins Dunkle bringen könnt. :gruebel: Liebe Grüße Hannes |
AW: Rückgabewert von Threads
Ich gehe hier gern einen anderen Weg:
Im Haupt-Thread lege ich eine Struktur an, in der die Ergebnisse der Threads gespeichert werden können (z.B. ein Array of Record). Diese Struktur schütze ich über eine CriticalSection. Der Thread schreibt seine Ergebnisse in diese Struktur und sendet dann eine Message an den Hauptthread, daß da was zu tun ist. Dann muss nur noch der Message-Handler des Hauptthread auf diese Message reagieren und gut ists Vorteil dieser Methode ist, daß nie jemand nach etwas pollen muss. Gruß Luggi |
AW: Rückgabewert von Threads
Man könnte aber auch Message+CS weglassen und von den Threads aus über Synchronize auf diese Struktur zugreifen.
Der Hauptthread braucht da nichts abzusichern. - wenn man statt dem Array eine TList nimmt, dann hat man eine gute Stelle, wo der Hauptthread dann auf die Änderungen reagiert. |
AW: Rückgabewert von Threads
Geht es dir denn in deiner Frage nur um die Ergebnissweitergabe an den Hauptthread, oder geht es auch darum, wieder neue Threads zu erzeugen, wenn die Zahle der Nebenthreads unter vier sinkt?
|
AW: Rückgabewert von Threads
@Jumpy: Es sollen alle Threads beendet und die Ergebnisse abgespeichert werden, bevor neue Aufgaben verteilt und somit neue Threads bis zur max. Anzahl gestartet werden.
Nach wie vor scheinen meine Ideen eher zusammengewürfelt und wenig optimal zu sein. Ach ja: Habs gerade mal mit
Delphi-Quellcode:
probiert, jedoch scheint der zugehörige fertige Thread nicht mitzuteilen, dass er fertig ist!?
waitformultipleobjects
|
AW: Rückgabewert von Threads
Wie wäre es mit einem Counter? Ich zietiere mal aus
![]() Zitat:
|
AW: Rückgabewert von Threads
Der Vorschlag von Jumpy geht in die Richtung, was in Java unter dem Namen "CountDownLatch" bekannt ist. Das ist eine Klasse, deren Instanzen mit einem bestimmten Wert initialisiert werden. Jeder Thread kann diesen Wert dann (z.B. nach Abschluss der Arbeit) um 1 verringern. Im Haupt-Thread genügt dann ein Aufruf der Methode "await". Dieser Aufruf blockiert, bis der Wert des Latches 0 ist. Wenn dieser Mechanismus mehr als einmal benötigt wird, wird stattdessen eine (Cyclic)Barrier verwendet.
Leider weiß ich nicht, was Delphi da von Haus aus kennt, aber vielleicht helfen dir die Stichworte Latch und Barrier ja schonmal weiter. lg |
AW: Rückgabewert von Threads
WaitForMultipleObjects passt hier nicht so ganz, da der Aufruf den Hauptthread und damit das Forumlar blockiert. Wie Uwe in #2 schon erwähnt hat, würde ich das auch mit dem OnTerminate Ereignis umsetzen.
Delphi-Quellcode:
procedure ButtonStartClick;
begin StartThreads; end; procedure StartThreads; begin if ActiveThreads <> 0 then Exit; // falls noch Threads laufen, keine neuen starten ActiveThreads := 4; // Anzahl laufender Threads setzen for i := 1 to ActiveThreads do TMyThread.Create.OnTerminate := OnThreadTerminate; // Threads starten und Event setzen end; procedure OnThreadTerminate; begin Dec(ActiveThreads); // Anzahl laufender Threads anpassen if ActiveThreads = 0 then // falls das der letzte von den 4 Threads war... StartThreads; // ...nächsten 4 Threads starten end; Wenn du dann noch FreeOnTerminate aller Threads auf true setzt, brauchst du dich auch nicht um die Freigabe der Threads zu kümmern. |
AW: Rückgabewert von Threads
Zitat:
|
AW: Rückgabewert von Threads
@Björn:
Wirklich ausgezeichnete Idee, den Start neuer Threads so zu lösen. :thumb: Vielen Dank soweit!! @patti: Hast du einen Vorschlag, wie man das lösen könnte? Vielleicht ein Pendant zu Critical Sections? Hannes |
AW: Rückgabewert von Threads
Das OnTerminate Event der TThread Klasse wird im Kontext des Hauptthreads aufgerufen. Von daher stellt das kein Problem dar.
|
AW: Rückgabewert von Threads
Oh stimmt, hätte ich doch vorher mal in die Hilfe geschaut...
Zitat:
|
AW: Rückgabewert von Threads
[ot]Steht das wirklich so in der Hilfe? Ich hab nicht nachgeschaut, aber das ist ja eine 1zu1 Übersetzung. :shock:[/ot]
|
AW: Rückgabewert von Threads
Jupp, gerade mit Hilfe der Delphi-Referenz gefunden:
![]() |
AW: Rückgabewert von Threads
So, an dieser Stelle möchte ich mich ganz herzlich bei euch für eure Mühe und Geduld, v.a. aber für euren Einfallsreichtum bedanken; ihr habt mir ein ganzen Stück weitergeholfen, sodass nun die Fertigstellung des besagten Programmes in greifbare Nähe rückt. Ein riesiges Dankeschön euch allen! :thumb:
Liebe Grüße Hannes |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:55 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