![]() |
WaitForMultipleObjects funktioniert irgendwie nicht
Hallo zusammen,
irgendwie funktioniert die SuFu nicht richtig... Suche nach "WaitForMultipleObjects" gibt kein Ergebnis zurück, obwohl ein solches Thema bereits ![]() Ist aber nicht ganz mein Thema: Ich möchte mehrere Worker-Threads für eine Suchfunktion benutzen und auf deren Ende warten. Jeder Thread liefert mir ein Ergebnis zurück welches ich auswerten möchte. Dafür ist, denke ich zumindest, die Funktion WaitForMultipleObjects gedacht. Hier mein Code:
Delphi-Quellcode:
Die Threads geben nun ihre Statusmeldungen korrekt aus. So weit so gut.TMyThread.Constructor( nMaxLaufzeit : Integer; AMemo : TMemo ); begin inherited Create( True ); FMaxLaufzeit := nMaxLaufzeit; FMemo := AMemo; FreeOnTerminate := True; Resume; end; TMyThread.ShowThreadStatus; begin Memo.Lines.Add( Format('Alive from thread %d, %d of %d',[self.Handle,FCurrent,FMaxLaufzeit]) ); end; TMyThread.Execute; begin FCurrent := FMaxLaufzeit; while not Terminated do begin Sleep(1000); Synchronize(ShowThreadStatus); Dec( FCurrent ); if FCurrent < 1 then Terminate; end; end; const MAX = 5; var ThreadList : array[0..MAX-1] of TMyThread; ThreadHandles : array[0..MAX-1] of THandle; i,ThreadsRunning : Integer; dw,idx : DWord; //Threads erzeugen und Handle-Liste füllen for i := 0 to MAX-1 do begin //Max. Laufzeit des Threads in Sekunden mitgeben ThreadList[i] := TMyThread.Create( (i+1)*3 ); ThreadHandles[i] := ThreadList[i].Handle; end; ThreadsRunning := MAX; while ThreadsRunning > 0 do begin //dw := WaitForMultipleObjects( MAX, @ThreadHandles, false, 0); //gleiches Ergebnis dw := WaitForMultipleObjects( MAX, @ThreadHandles[0], false, 0); if (dw <> WAIT_TIMEOUT) AND (dw <> WAIT_FAILED) then begin //Array-Index des auslösenden Threads errechnen idx := dw - WAIT_OBJECT_0; if idx < MAX then begin Memo.Lines.Add( Format('Thread %d (Handle:%d) beendet.',[idx,ThreadHandles[idx]]) ); Dec( ThreadsRunning ); end; end; Application.ProcessMessages; end; Nun erwarte ich, dass ich für jeden Thread, der sich beendet ein "Signal" bekomme. Ist aber leider nicht so :wall: Einmal bekomme ich ein "gültigen" Index (2), danach immer nur WAIT_FAILED? Verstehe ich den Sinn der Funktion ncht richtig oder mache ich irgendwas falsch? lg, Michael |
Re: WaitForMultipleObjects funktioniert irgendwie nicht
Zum Fehler:
Nachdem der erste Thread beendet ist, übergibst du eine falsche Anzahl an Threadhandles inkl. eines ungültigen Handles an die Funktion. Du musst dein Array verkürzen bzw. umsortieren. Allgemein: Schau dir mal MsgWaitforMultipleObjects an, damit du nicht ständig durch dein Programm rennst, sondern nur, wenn auch wirklich was passiert. Zum Suchen: Ich glaube in der DP war eine maximale Länge (20 Zeichen?) der Suchbegriffe ein Problem. Nutze besser ref.dp200x ! |
Re: WaitForMultipleObjects funktioniert irgendwie nicht
Hallo sirius,
hmmm... ich war gerade dabei das Array zu verkürzen, als ich Deine Nachricht gelesen habe :thumb: Und funktioniert... danke.
Delphi-Quellcode:
var
ThreadHandles : array of THandle; ... SetLength(ThreadHandles,MAX); ... ThreadsRunning := MAX; while ThreadsRunning > 0 do begin dw := WaitForMultipleObjects( ThreadsRunning, @ThreadHandles[0], false, 0); if (dw <> WAIT_TIMEOUT) AND (dw <> WAIT_FAILED) then begin //Array-Index des auslösenden Threads errechnen idx := dw - WAIT_OBJECT_0; if idx < MAX then begin Memo.Lines.Add( Format('Thread %d (Handle:%d) beendet.',[idx,ThreadHandles[idx]]) ); Dec( ThreadsRunning ); //Wenn nicht letztes Element signalisiert wurde, dann letztes Element dem Signalisiertem zuweisen if idx <> ThreadsRunning then ThreadHandles[idx] := ThreadHandles[ThreadsRunning]; //Letztes Element abschneiden SetLength(ThreadHandles,ThreadsRunning); end; end; Application.ProcessMessages; end; Komisch finde ich, dass sich mein Thread gar nicht "richtig" meldet, wenn er aus dem Execute raus kommt. Ich bekomme das Signal nur, wenn ich am Ende explizit "TerminateThread" aufrufe - :gruebel: Noch'n Fehler?
Delphi-Quellcode:
TMyThread.Execute;
begin FCurrent := FMaxLaufzeit; while not Terminated do begin Sleep(1000); Synchronize(ShowThreadStatus); Dec( FCurrent ); if FCurrent < 1 then Terminate; end; //Ansonsten wird das Thread-Ende nicht signalisiert!) TerminateThread( self.Handle, 0 ); end; Ich habe MsgWaitForMultipleObjects bereits mir diversen Events erfolgreich getestet. Hing halt bei der obigen Variante fest... gleich mal weiter tippen. Und die "ref.dp200x" kannte ich noch gar nicht... :cyclops: |
Re: WaitForMultipleObjects funktioniert irgendwie nicht
Zitat:
|
Re: WaitForMultipleObjects funktioniert irgendwie nicht
Wahrscheinlich liegt es an der guten alten Delphi 5 Version, die hier so vor sich hinwerkelt :roll:
Dort wird (noch) kein Aufruf von ExitThread gemacht:
Delphi-Quellcode:
***** Classes.pas ******
<--schnipp--> destructor TThread.Destroy; begin if not FFinished and not Suspended then begin Terminate; WaitFor; end; if FHandle <> 0 then CloseHandle(FHandle); inherited Destroy; //von TObject RemoveThread; end; <--schnapp--> <--schnipp--> procedure RemoveThread; begin EnterCriticalSection(ThreadLock); try if ThreadCount = 1 then PostMessage(ThreadWindow, CM_DESTROYWINDOW, 0, 0); finally LeaveCriticalSection(ThreadLock); end; end; <--schnapp--> |
Re: WaitForMultipleObjects funktioniert irgendwie nicht
Dann such mal in der Unit nach "endthread" bzw. der funktion ThreadProc.
Edit: Aber wie gesagt, beim herauslaufen aus der ThreadFunc wird der Thread auch beendet. Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:43 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