AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Erkennen ob irgendein Thread beendet wird.
Thema durchsuchen
Ansicht
Themen-Optionen

Erkennen ob irgendein Thread beendet wird.

Ein Thema von himitsu · begonnen am 3. Mär 2012 · letzter Beitrag vom 4. Mär 2012
Antwort Antwort
Benutzerbild von himitsu
himitsu

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

Erkennen ob irgendein Thread beendet wird.

  Alt 3. Mär 2012, 16:05
Delphi-Version: XE
Moin,

ich hab zwei Funktionen, welche sich aber noch nicht kennen.

In der Ersten wird ein thread-globaler Wert (Variant) gesetzt, welcher von der Zweiten eventuell ausgelesen wird.
Wobei die Zweite nicht immer ausgeführt wird und erst die zweite Prozedur kennt quasi die Zusammenhänge, über den threadvar.

Theoretisch hätte ich nun eine threadvar deklariert, aber leider geht das mit dem Variant nicht, da es so eventuell ein Speicherleck ergeben könnte.

Nun müßte ich also entweder die threadvar manuell freigeben oder die Werte in einer Liste, zusammen mit der Thread-ID, verwalten.
So oder so, ich müßte irgendwie auf das Ende des Threads reagieren, um den Wert freizugeben.
- bei der threadvar würde es sonst ein Speicherleck ergeben
- oder die Liste wird unkontrolliert anwachsen, da ich ja nie weiß welcher Wert eventuell noch gebraucht wird oder was weg kann



Wie kann ich also auf das Ende eines Thread reagieren?
Egal ob über TThread oder direkt über die WinAPI erstellt.



Alternativ müßte ich das Speichermanagement des Variants verändern und/oder dessen mögliche Werte eventuell einschränken.
Keine Interfaces, Strings und Co. erlauben. Oder z.B. die enthaltenen Strings auf ein statiches Array umleiten (ebenfalls als threadvar, mit einer festgelegten maximalen Länge).
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

AW: Erkennen ob irgendein Thread beendet wird.

  Alt 3. Mär 2012, 16:08
Guck dir mal die WaitForXXX Funktionen an.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Erkennen ob irgendein Thread beendet wird.

  Alt 3. Mär 2012, 16:29
Ich will ja nicht warten.
Beide "zusammengehörigen" Prozeduren laufen im jeweils selben Thread ab.

OK, oder ich darf ständig die ganze Liste pollend durchgehn und schauen was noch aktuell ist.
Eine Art Event wäre mir da schon lieber.

Ansonsten werde ich wohl eher den Variant beschränken.
$2B or not $2B

Geändert von himitsu ( 3. Mär 2012 um 16:49 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von divBy0
divBy0

Registriert seit: 4. Mär 2007
Ort: Sponheim
1.021 Beiträge
 
Delphi XE2 Professional
 
#4

AW: Erkennen ob irgendein Thread beendet wird.

  Alt 3. Mär 2012, 21:46
Ich weiß nicht ob richtig verstanden habe was du meinst, aber es gibt doch das OnTerminate-Ereignis.
Marc
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt, die 10. summt die Melodie von Tetris... | Wenn das die Lösung ist, dann hätte ich gerne mein Problem zurück! | engbarth.es
  Mit Zitat antworten Zitat
sahimba

Registriert seit: 14. Nov 2011
Ort: Berlin, Hauptstadt der DDR
137 Beiträge
 
Delphi 10 Seattle Professional
 
#5

AW: Erkennen ob irgendein Thread beendet wird.

  Alt 3. Mär 2012, 22:08
Eine schnell skizzierte Idee: baue eine DLL, in welcher Du eine Callbackfunktion implementierst. Diese DLL lädst Du in Deinen Prozess. Der Einsprungpunkt der DLL (DllMain) reagiert auf DLL_THREAD_ATTACH und inbesondere, um das Ende eines "beliebigen" Threads Dir zu signalisieren, auf DLL_THREAD_DETACH. DLL_THREAD_DETACH wird im Kontext des beendeten (also quasi im Zustand des beendet werdens) Threads ausgeführt. So kannst Du dann auch Deine Threadvars löschen/freigeben/knutschen.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Erkennen ob irgendein Thread beendet wird.

  Alt 3. Mär 2012, 23:27
Es geht um eine Komponente und da werde ich nicht noch eine DLL mitliefern, außerdem bin nicht ich derjenige, welcher den Thread startet oder beendet.

Es geht immernoch um eine Komponente und da kann ich nicht einfach so fremde Ereignismethoden überschreiben. (Woher soll ich denn wissen, ob die nich schon belegt sind? )
Und wie schon erwähnt, geht es nicht nur um TThread-Threads, womit das OnTerminate eh wegfällt.



Es gibt eine Methode SetzeWert, welche für den aktiven Thread einen Wert ablegt, als threadvar.

Später wird irgendwann eventuell eine weitere Methode aufgerufen, welche diesen Wert verarbeitet, falls Einer vorhanden ist.



Das Problem ist eben, daß threadvars über keine Finalizierung verfügen, so daß es zu Speicherlecks kommen könnte, wenn die enthaltenen Daten nur referenziert sind, wie es z.B. bei Strings und Interfaces der Fall ist.



Aber ich glaub ich hab eine Lösung. Mal sehn ob es auch so funktioniert, wie ich es mir ausgedacht hab.
Über eine weitere threadvar wird geregelt, ob für den aktiven Thread ein Wert abgelegt werden darf und wenn, dann wird über ein Interface die Freigabe erledigt.
$2B or not $2B
  Mit Zitat antworten Zitat
ASM

Registriert seit: 16. Aug 2004
165 Beiträge
 
Delphi 7 Enterprise
 
#7

AW: Erkennen ob irgendein Thread beendet wird.

  Alt 3. Mär 2012, 23:53
Wie kann ich also auf das Ende eines Thread reagieren?
Egal ob über TThread oder direkt über die WinAPI erstellt.
Wäre das im konkreten Fall mit Hilfe eines Eventhandlers vielleicht wie folgt zu realisieren, wobei das hier nur als Grundgerüst konzipiert ist, da ich die Einzelheiten des speziellen Projekts nicht kenne ?:

Delphi-Quellcode:
type
  TMySpecialthread = class(TThread)
  Begin
   {...}
  protected
      procedure Execute; override;
   {...}    
  end;
  
Var
  EventHandle: THandle;
  ThreadHandle: THandle;
  MySpecialthread: TMySpecialthread;
  
procedure ToDoAfterMySpecialThreadHasFinished; stdcall;
Var ObjRtn: Cardinal;
begin
  ObjRtn := WaitForSingleObject(EventHandle, INFINITE);
  MySpecialThread.Terminate;
  Showmessage('MySpecialThread is Ready'); // eben nur als Beispiel
  { ..  DoToListe abarbeiten,
    was nach Ende des MySpecialThread zu erledigen ist ... }

  ExitThread(0);
end;

procedure MySpecialthread.Execute;
begin
   {... do it  .....}
  SetEvent(EventHandle);
end;
  
procedure TForm1.FormCreate(Sender: TObject);
var
  ThreadID: Cardinal;
begin
  EventHandle := CreateEvent(Nil, True, False, 'MySpecialThreadEvent');
  ThreadHandle := CreateThread(nil, 0, @ToDoAfterMySpecialThreadHasFinished, nil, 0, ThreadId);
  MySpecialThread:=TMySpecialThread.create(false);
  MySpecialThread.FreeOnTerminate:=false; // oder nach Bedarf true
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Button1.Enabled:=false;
  MySpecialThread.Resume;
end;
  Mit Zitat antworten Zitat
sahimba

Registriert seit: 14. Nov 2011
Ort: Berlin, Hauptstadt der DDR
137 Beiträge
 
Delphi 10 Seattle Professional
 
#8

AW: Erkennen ob irgendein Thread beendet wird.

  Alt 3. Mär 2012, 23:57
Es geht um eine Komponente und da werde ich nicht noch eine DLL mitliefern, außerdem bin nicht ich derjenige, welcher den Thread startet oder beendet.
Gerade weil Du nicht derjenige bist, welcher den/die Thread(s) startet, wäre die Lösung möglich, informiert sie Dich doch über die Start und Beendigung eines >jeglichen< Threads. Unabhängig davon, ob selbst erstellt oder nicht. Das Argument, dass es sich um eine Komponente handelt zu welcher Du nicht noch eine DLL mitliefern willst, ist hingegen nachvollziehbar, war aber (oder ich habe es überlesen) hier nicht bekannt.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Erkennen ob irgendein Thread beendet wird.

  Alt 4. Mär 2012, 00:57
Nunja, ich bin dabei meine Codes aufzuräumen und unter Anderem wird auch ein abstraktes Logging-System mit integriert.
(es hat selber keine Logfunktion, sondern dient nur als Schnittstelle für gewisse Grundfunktionen, um dort später irgendein Loggsystem, wie z.B. Eurekalog oder sonstewas, dort anhängen zu können)

Nun gibt es da auch folgene Methode, welche man auf unterschiedliche Weise nutzen kann, wie z.B.:
Delphi-Quellcode:
begin
  HLog.EnterMethod('Name der Prozedur'); // eventuell auch ohne Name HLog.EnterMethod;
  ...
  HLog.ExitMethod;
end;

begin
  HLog.EnterMethod('Prozedur');
  ...
  HLog.ExitMethod(Result); // oder man loggt auch noch das Result mit
end;

begin
  HLog.EnterMethod('Prozedur');
  ...
end; // HLog.ExitMethod wird automatisch aufgerufen (über ein lokales Interface)

var M: HLog.IMethod;
begin
  M := HLog.EnterMethod('Prozedur');
  ...
  M.ExitMethod(Result);
end;
Das "Event" wird allerdings erst richtig abgeschlossen, wenn die Prozedur richtig abgeschlossen wurde (über das Interface), womit auch Folgendes keine Probleme bereitet.
Delphi-Quellcode:
begin
  HLog.EnterMethod('Name der Prozedur'); // eventuell auch ohne Name HLog.EnterMethod;
  ...
  HLog.ExitMethod;
  ...
  HLog.ExitMethod(Result); // hier wird Result nur zwischengespeichert
  ...
end; // hier wird das Result erst geloggt
Bei den ersten Varianten, wo nicht explizit über das IMethod-Interface gegangen wird
und vorallem bei Multithreadanwendungen gibt es keinen physischen Zusammenhang, zwischen den einzelnen Aufrufen.
OK, jetzt könnte man zwar über die ThreadID ganz billig im ExitMethod das IMethod des aktuellen Threads raussuchen, aber davon muß es nicht nur Eines geben ... Stichwort rekursive Aufrufe.

Ich find ja die "globalen" Methoden am handlichsten, aber da fehlt eben die direkte Zusammengehörigkeit.
Weswegen es mit eigentlich am schönsten gefallen würde, das globale ExitMethod behalten zu können.

Gut, ich könnte auch eine Liste führen (als threadvar) und dann statt auf ein treadvar-ResultSave direkt auf das letzte IMethod verweisen, aber über eine globale IMethod-Variable könnte man die Erstellungs/Freigabe-Reihenfolge von verschachtelt erstellten IMethods eines Threads durcheinanderbringen.



Ist halt alles nicht so einfach.
Aber es soll auch was Ordentliches werden, womit ich dann die nächsten Jahre gut leben kann, wenn ich es bei mir überall als Basissystem einsetze.
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort


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 18:33 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