AGB  ·  Datenschutz  ·  Impressum  







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

Rückgabewert von Threads

Ein Thema von Hannes91 · begonnen am 6. Sep 2011 · letzter Beitrag vom 7. Sep 2011
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Hannes91
Hannes91

Registriert seit: 28. Aug 2010
Ort: Hamburg
15 Beiträge
 
Delphi 2010 Professional
 
#1

Rückgabewert von Threads

  Alt 6. Sep 2011, 20:18
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
Hannes
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#2

AW: Rückgabewert von Threads

  Alt 6. Sep 2011, 20:28
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).
Du kannst im OnTerminate auf den Parameter Sender zurückgreifen, der dir die Instanz des gerade beendeten Threads liefert. Mit is und as kannst du dann auf deine speziellen Thread-Klasse zugreifen.

Oder du verwendest pro Thread-Instanz eine andere Event-Methode.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Hannes91
Hannes91

Registriert seit: 28. Aug 2010
Ort: Hamburg
15 Beiträge
 
Delphi 2010 Professional
 
#3

AW: Rückgabewert von Threads

  Alt 6. Sep 2011, 22:06
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 !

Einen schönen Abend noch

Hannes
Hannes
  Mit Zitat antworten Zitat
Benutzerbild von Hannes91
Hannes91

Registriert seit: 28. Aug 2010
Ort: Hamburg
15 Beiträge
 
Delphi 2010 Professional
 
#4

AW: Rückgabewert von Threads

  Alt 7. Sep 2011, 12:50
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 for i := 0 to iBloecke - 1 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.
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.
  • Wäre es hier möglich, Waitformultipleobjects(length(lpHandles), @lpHandles[0], true, INFINITE); zu nehmen?
  • Könnte es bei "kurzen" Aufträgen zu Problemen kommen, dass der Thread schon vor Aufruf von waitformultipleobjects beendet ist, welcher erst nach Start der max. Anzahl an Threads bei (i mod iThreads = iThreads - 1) or (i = iBloecke - 1) erfolgt?
  • Wie ist die zeitliche Reihenfolge - Ende von Execute --> OnTerminate(Aufruf einer Methode) --> bis hier wartet waitfor... ?
  • Wer muss den Thread wie schließen / schließt er sich doch selbst?

Ich hoffe doch inständig, dass ihr mir da etwas Licht ins Dunkle bringen könnt.

Liebe Grüße

Hannes
Hannes
  Mit Zitat antworten Zitat
grl

Registriert seit: 5. Feb 2007
174 Beiträge
 
FreePascal / Lazarus
 
#5

AW: Rückgabewert von Threads

  Alt 7. Sep 2011, 13:27
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
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

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

AW: Rückgabewert von Threads

  Alt 7. Sep 2011, 14:27
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.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.736 Beiträge
 
Delphi 6 Enterprise
 
#7

AW: Rückgabewert von Threads

  Alt 7. Sep 2011, 14:38
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?
Ralph
  Mit Zitat antworten Zitat
Benutzerbild von Hannes91
Hannes91

Registriert seit: 28. Aug 2010
Ort: Hamburg
15 Beiträge
 
Delphi 2010 Professional
 
#8

AW: Rückgabewert von Threads

  Alt 7. Sep 2011, 14:47
@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 waitformultipleobjects probiert, jedoch scheint der zugehörige fertige Thread nicht mitzuteilen, dass er fertig ist!?
Hannes
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.736 Beiträge
 
Delphi 6 Enterprise
 
#9

AW: Rückgabewert von Threads

  Alt 7. Sep 2011, 15:08
Wie wäre es mit einem Counter? Ich zietiere mal aus diesem Delphi-Treff-Tutorial:

Zitat:
...Und hier wird es nun spannend. Nachdem die Arrays noch einmal neu gefüllt werden, wird ein interner Thread-Zähler auf 3 gesetzt. Dann werden die Threads gestartet:
Code:
with TBubbleSort.Create(BubbleSortBox, BubbleSortArray) do
  OnTerminate := ThreadDone;
Durch den Aufruf des Konstruktors Create wird auch automatisch die Execute-Methode aufgerufen, so dass der Thread startet. Außerdem wird dem Thread hier noch mitgeteilt, dass er auf das OnTerminate-Ereignis mit dem Ausführen der Methode "ThreadDone" reagieren soll. OnTerminate wird ausgelöst, sobald ein Thread fertig abgelaufen ist.
Nun laufen die Threads also, und in der Variablen ThreadsRunning steht, wie viele es sind. Ist ein Thread fertig, wird der Wert in ThreadDone um 1 reduziert. Sind alle Threads mit dem Sortieren am Ende angekommen, ist die Variable 0, und der Start-Button wird wieder verfügbar gemacht.
Ich bin bei Threads auch noch recht unerfahren, aber kann man nicht in deinem fall nach der Schleife, die die Threads erzeugt eine neue "Warteschleife" starten, die solange läuft (und nix macht) bis der Counter auf 0 steht? Oder die wie im Bsp. im OnTerminate eines Threads ausgeführte-Funktion veringert den Counter und schaut ob er schon null ist (also der letzte Thread fertig) und startet dann eine neue Prozedur, mit der es weitergeht und die die gesammelten Werte weiterverarbeitet...
Ralph

Geändert von Jumpy ( 7. Sep 2011 um 15:13 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von patti
patti

Registriert seit: 20. Okt 2004
Ort: Mittelfranken
665 Beiträge
 
Turbo Delphi für Win32
 
#10

AW: Rückgabewert von Threads

  Alt 7. Sep 2011, 15:23
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
Patrick Kreutzer
[Informatik-Student im 4. Semester]
http://www.patti-k.de/
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 21:03 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