![]() |
WaitForMultipleObjects erkennt Beendigung von Threads nicht
Hallo, ich bins mal wieder! :-D
Ich erstelle unterschiedlich viele Threads, auf deren Beendigung das Programm warten soll. Bisher hab ich immer über das OnTerminate-Ereignis der Threads die Anzahl der Threads runtergezählt und mit
Delphi-Quellcode:
auf die Threads gewartet. Nun ist das natürlich höchst unschön und ich denke, dass es mit WaitForMultipleObjects effizienter wäre.
while ThreadAnzahl > 0 do
begin Sleep(1); Application.ProcessMessages; end; Leider kapiert WaitForMultipleObjects aber nie, dass die Threads beendet wurden :( Hier die Prozedur, in der die Threads erzeugt werden:
Delphi-Quellcode:
LG,
function Unterschiede_markieren(Bild1, Bild2: TBitmap; Blend: Real; Toleranz: Byte):TBitmap;
VAR i,j,Breite,Hoehe,Itert:integer; B1,B2: ColorArray; SysInfo: TSystemInfo; HandleArray: array of THandle; begin GetSystemInfo(SysInfo); ThreadCount:=SysInfo.dwNumberOfProcessors; SetLength(Thread, ThreadCount); SetLength(HandleArray, Threadcount); result:=TBitmap.Create; if NOT Assigned(fertig_Bild) then fertig_Bild:=TBitmap.Create; fertig_Bild.Width:=Bild2.Width; fertig_Bild.Height:=Bild2.Height; for i := 0 to ThreadCount-1 do begin Thread[i]:=TDifference_Finder.Create(Bild1, Bild2, Round(i*Bild2.Height/ThreadCount), Round((i+1)*(Bild2.Height-1)/ThreadCount), Blend, Toleranz, true); HandleArray[i]:=Thread[i].Handle; Thread[i].FreeOnTerminate:=true; Thread[i].Resume; end; WaitForMultipleObjects(Length(HandleArray), @HandleArray[0] ,true, INFINITE); result.Assign(fertig_Bild); end; Pussyranger |
AW: WaitForMultipleObjects erkennt Beendigung von Threads nicht
EDIT: Rufst du in den Threads synchronize oder ähnliches auf? Das könnte einen netten Deadlock geben.
[EDIT]Vermutlich Blödsinn: [/EDIT] Könnte es sein, dass ein Thread schon fertig ist, wenn WaitForMultipleObjects aufgerufen wird? Wie sich WaitForMultipleObjects dann verhält, habe ich nicht gefunden. Rufe mal am Ende des Threads ein
Delphi-Quellcode:
(bzw. einen Zeitraum, indem das Warten auf jeden Fall ausgelöst wird) auf und gucke, ob das dass Problem behebt.
sleep(1000);
|
AW: WaitForMultipleObjects erkennt Beendigung von Threads nicht
Irgendwie ja schon komisch ... da wird die Berechnung in den Hintergrund geschickt und im Vordergrund wird der Thread schlafen gelegt ... irgendwie hatte ich das mit den Threads anders in Erinnerung ...
Ab in den Hintergrund und wenn alle fertig sind - Reaktion auf das OnTerminate-Event - dann die Ergebnisse zusammentragen und ausgeben. |
AW: WaitForMultipleObjects erkennt Beendigung von Threads nicht
Moin moin,
hast du geprüft, ob wirklich alle Threads beendet sind? |
AW: WaitForMultipleObjects erkennt Beendigung von Threads nicht
Eventuell gibt es aber auch eine Zugriffsverletzung in den Threads, da ja die Threads auf die gleichen Objekte zugreifen (Bild1, Bild2) ... und sogar noch auf fertig_bild!
TBitmap ist nicht threadsicher ... das hatten wir doch schon ;) |
AW: WaitForMultipleObjects erkennt Beendigung von Threads nicht
Delphi-Quellcode:
bewirkt nichts.
Sleep(1000);
Da alle Threads zumindest das OnTerminate-Ereignis auslösen, nehme ich an, dass die Threads dann auch beendet werden. Eine Zugriffsverletzung gibt es denke ich nicht, denn bisher hat ja alles wunderbar funktioniert. Die Threads werden synchronisiert, bevor auf fertig_Bild zugegriffen wird. |
AW: WaitForMultipleObjects erkennt Beendigung von Threads nicht
Zitat:
Dein Main-Tread wartet allerdings auf deine Arbeitsthreads. :arrow: Klassischer Deadlock. |
AW: WaitForMultipleObjects erkennt Beendigung von Threads nicht
Am Synchronize hats gelegen! Allerdings muss ich ja irgendwie die Teilbilder zusammenfügen.
Übers OnTerminate-Ereignis geht es nicht, da das auch zu einem DeadLock führen würde. Nun habe ich die Deklaration für die Teilbilder in den public-Bereich geschrieben. Wenn WaitForMultipleObjects beendet ist, rufe ich folgenden Code auf:
Delphi-Quellcode:
Trotzdem wird der Speicher von Finish nicht wieder freigeben. Wieso?
for i := 0 to ThreadCount-1 do
begin fertig_Bild.Canvas.Draw(0, Thread[i].StartYt, Thread[i].Finish); Thread[i].Finish.Free; end; Edit: FreeOnTerminate hab ich auf false gesetzt. |
AW: WaitForMultipleObjects erkennt Beendigung von Threads nicht
Zitat:
Die Zahl im Taskmanager muss auf solche Änderung nicht reagieren. |
AW: WaitForMultipleObjects erkennt Beendigung von Threads nicht
Ich wollte die Prozedur 100 Mal hintereinander aufrufen. Dabei hat mir der Taskmanager für das Programm zwar immer maximal 800MB angezeigt, aber die Auslastung des RAM insgesamt ist kontinuierlich bis auf 100% gestiegen.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:34 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