AGB  ·  Datenschutz  ·  Impressum  







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

Threads verstehen...

Ein Thema von Gambit · begonnen am 30. Apr 2005 · letzter Beitrag vom 1. Mai 2005
Antwort Antwort
Gambit

Registriert seit: 28. Mai 2003
680 Beiträge
 
Delphi 7 Professional
 
#1

Threads verstehen...

  Alt 30. Apr 2005, 20:31
Hallo,
in meinem anderen Thread(Thread beenden) hatte ich über unerklärliche Hänger in meinem Programm berichtet. Ich habe mal versucht den Fehler zu finden und dazu folgendes kleines Testprogramm mit dem ich dem Fehler scheinbar etwas auf die Spur gehkommen bin. Er liegt im Thread. Dazu erstmal folgende kleine Threadklasse:

Delphi-Quellcode:
unit unit2 ;
interface
uses Classes,windows;

type TConThread = class(TThread)
  private
    fErrCode: Integer;
  public
    constructor Create(CreateSuspended: boolean);
  protected
    procedure Execute; override;
  published
    property ErrCode: integer read fErrCode;
  end;


implementation

constructor TConThread.create(CreateSuspended: boolean);
begin
  inherited create(CreateSuspended);
  freeOnTerminate:= true;
  fErrCode:= -1;
end;


procedure TConThread.Execute;
begin
  Try
    fErrCode:= 0;
    terminate;
  except
    fErrCode:= 1;
    terminate;
  end;
  if Terminated then
    exit;

end;

end.
Der Thread kann eigentlich immer nur die Zahl Null liefern, weil der Except-Block nicht ausgeführt wird.

Wenn ich jetzt folgendes mache:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
    i, count: Integer;
begin
  Count:= 0;
  memo1.Lines.Clear;
  memo2.Lines.Clear;
  for i:= 0 to 1000 do
  begin
    aCon:= TConThread.Create(false);
    repeat until (aCon.ErrCode = 0) or ((aCon.ErrCode <> 0) and (aCon.ErrCode <> -1));
    if (aCon.ErrCode <> 0) and (aCon.ErrCode <> -1) then
    begin
      memo2.Lines.Add(intToStr(aCon.ErrCode));
      count:= count+1;
    end;
    memo1.Lines.Add(intToStr(aCon.ErrCode));
  end;
  showMessage(intToStr(count));
end;
stelle ich fest, dass ich in den allermeisten Fällen auch Null zurückbekomme, manchmal aber eben auch nicht. Ich habe bei 1000 Schleifendurchläufen meistens 1-2 oder dreimal etwas anderes bekommen nämlich 76 (woher es das nimmt ist mir schleierhaft)

Bei 100.000 Duchläufen hatte ich einmal 300 und einmal 305 mal die 76.
Bei 1.000.000 Durchläufen dann plötzlich wieder nur 56 mal die Zahl 76.

So, und jetzt kommt ihr...

Gambit
  Mit Zitat antworten Zitat
Waldteufel
(Gast)

n/a Beiträge
 
#2

Re: Threads verstehen...

  Alt 30. Apr 2005, 22:03
Hi.

Sofern die Property FreeOnTerminate gesetzt ist, wird der Speicherbereich des Threads beim Terminieren freigegeben und ggf. durch andere Programme genutzt. Setze einfach FreeOnTerminate auf false und das Problem ist gelöst!
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#3

Re: Threads verstehen...

  Alt 30. Apr 2005, 23:01
Du kannst im Übrigen auf die terminate; und exit; Aufrufe verzichten, da der Thread eh zu ende ist
(man macht meist while not Terminated do ... )
  Mit Zitat antworten Zitat
Gambit

Registriert seit: 28. Mai 2003
680 Beiträge
 
Delphi 7 Professional
 
#4

Re: Threads verstehen...

  Alt 1. Mai 2005, 14:06
OK, habe jetzt mal FreeOnTerminate auf false gesetzt. Dann muss ich ja den Speicher wohl selbst wieder freigeben, oder?

habe das dann hier eingebaut:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
    i, count: Integer;
begin
  Count:= 0;
  memo1.Lines.Clear;
  memo2.Lines.Clear;
  for i:= 0 to 1000 do
  begin
    aCon:= TConThread.Create(false);
    repeat
    until (aCon.ErrCode = 0) or ((aCon.ErrCode <> 0) and (aCon.ErrCode <> -1));
    if (aCon.ErrCode <> 0) and (aCon.ErrCode <> -1) then
    begin
      memo2.Lines.Add(intToStr(aCon.ErrCode));
      count:= count+1;
    end;
    memo1.Lines.Add(intToStr(aCon.ErrCode));
    aCon.Free; // Hier gebe ich den Speicher wieder frei...
  end;
  showMessage(intToStr(count));
end;
Wäre das so dann OK?

Gruß

Gambit
  Mit Zitat antworten Zitat
Benutzerbild von Dani
Dani

Registriert seit: 19. Jan 2003
732 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: Threads verstehen...

  Alt 1. Mai 2005, 14:35
Hi,

[smartypants]
In deinem Beispiel wartest du mit Repeat...Until auf die Beendigung der Threads. Das führt aber dazu, dass dein Programm in der ButtonClick Routine hängen bleibt, bis der Thread beendet wird - mit dem Effekt, dass Benutzereingaben nicht mehr abgearbeitet werden. Das Programm ließe sich dann im Extremfall nur noch mit dem Taskmanager beenden.[/smartypants] (Oder ist das jetzt Absicht? )
Dani H.
At Least I Can Say I Tried
  Mit Zitat antworten Zitat
Gambit

Registriert seit: 28. Mai 2003
680 Beiträge
 
Delphi 7 Professional
 
#6

Re: Threads verstehen...

  Alt 1. Mai 2005, 14:48
Theoretisch hast du recht, ich wüsste aber auch nicht, wie ichs anders machen sollte. Der Thread soll letztendlich dazu dienen, eine Verbindung zu einer Datenbank aufzubauen. Klappt der Verbindungsaufbau liefert die Execute-Methode den Wert 0 ansonsten den Wert 1. Ich muss aber solange warten, bis ich einen von beiden Werten erhalte, weil ich im Folgenden ja Datenbankabfragen mache und die gehen halt ohne Verbindung nicht. Eigentlich sollte der Thread aber eine von beiden Werten umgehend liefern.
Den Verbindungsaufbau will ich per Thead machen, damit nicht während des Aufbau alles einfriert und ich zB. eine kleine Warteanimation auf eine Form legen kann...
  Mit Zitat antworten Zitat
Benutzerbild von Dani
Dani

Registriert seit: 19. Jan 2003
732 Beiträge
 
Turbo Delphi für Win32
 
#7

Re: Threads verstehen...

  Alt 1. Mai 2005, 14:54
Pack die Threads in eine Liste, dann kannst du z.B. in einem Timer prüfen, ob noch Threads laufen. Der Thread muss sich nur selbst aus der Liste austragen, wenn er seine Arbeit beendet hat.
Dani H.
At Least I Can Say I Tried
  Mit Zitat antworten Zitat
Gambit

Registriert seit: 28. Mai 2003
680 Beiträge
 
Delphi 7 Professional
 
#8

Re: Threads verstehen...

  Alt 1. Mai 2005, 15:06
hmmm, ja, könnte man so machen. Was mich wundert ist, nachdem ich den Speicher mit aCon.free freigegeben habe, kann ich immer noch aCon.ErrCode abfragen...
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#9

Re: Threads verstehen...

  Alt 1. Mai 2005, 16:47
Und zwar aus dem gleichen Grund, warum du anfangs 76 statt 0 auslesen konntest.

Grüße vom marabu
  Mit Zitat antworten Zitat
Lasse2002

Registriert seit: 29. Nov 2004
79 Beiträge
 
RAD-Studio 2009 Pro
 
#10

Re: Threads verstehen...

  Alt 1. Mai 2005, 16:50
Jetzt war jemand schneller, aber trotzdem:

Du hast zwar den Speicher freigegeben, aber nicht gelöscht. Daher kannst Du den Wert lesen. Du hättest aber auch eine Zugriffsverletzung gekommen können.

Übrigens kannst Du auch mit aCon.WaitFor auf die Beendigung des Threads warten. Dein Programm hat nämlich sonst 100% CPU Nutzung. Das macht die Threadausführung deutlich langsamer. Und Notebookbesitzer wundern sich, warum der Akku so schnell leer wird
Lasse
  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 20:02 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