AGB  ·  Datenschutz  ·  Impressum  







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

Handle count erhöht sich permanent

Ein Thema von Klaus01 · begonnen am 22. Okt 2014 · letzter Beitrag vom 22. Okt 2014
Antwort Antwort
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.771 Beiträge
 
Delphi 10.4 Sydney
 
#1

Handle count erhöht sich permanent

  Alt 22. Okt 2014, 11:57
Hallo,

ich weiß nicht mehr weiter..

Ich habe einen Threadpool (poolsize = 2xcpuCount).

Delphi-Quellcode:
procedure TThreadpool.Execute;
var
  i: Byte;
begin
  while not terminated do
    begin
      try
        if (fRunningTasks.count < fPoolSize) and (fTaskList.Count > 0) then
          begin
            fRunningTasks.Insert(0,fTaskList[0]);
            fTaskList.Delete(0);
            fRunningTasks[0].Start;
          end;
      except
        on E:Exception do
          fLogger.add(1,format('%s: Error while inserting task: %s',[self.ClassName,E.Message]));
      end;

      try
        if fRunningTasks.count > 0 then
          for i:= fRunningTasks.Count -1 downto 0 do
            begin
              if fRunningTasks[i].finished then
                begin
                  fRunningTasks[i].Free;
                  fRunningTasks.Delete(i);
                end;
            end;
        sleep(50);
      except
        on E:Exception do
          fLogger.add(1,format('%s: Error while deleting tasks: %s',[self.ClassName, E.Message]));
      end;
    end;
end;
Die Tasks sind auch Threads (freeOnTerminate = false).

fRunningTasks ist eine generische TList.

Ich weiß es ist nicht optimal die laufenden Threads in einer Schleife zu überwachen..

Die Tasks werden alle 5 Minuten ausgeführt.
Es werden 173 Tasks abgearbeitet.

Nach jedem Durchlauf erhöht sich die Anzahl der Handles im Windows TaskManager um 173.
Der "Speicherverbrauch" um ca 300kByte.
Die Anzahl der Thread geht aber nachdem ein Durchlauf beendet wurde wieder auf den Normalwert (2) zurück.
Meiner Meinung nach, werden die Tasks(Threads) ordnungsgemäß beendet.

Warum erhöht sich dann noch die Anzahl der Handles?

Grüße
Klaus
Klaus

Geändert von Klaus01 (22. Okt 2014 um 12:19 Uhr)
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Handle count erhöht sich permanent

  Alt 22. Okt 2014, 12:03
Meiner Meinung nach, werden die Tasks(Threads) ordnungsgemäß beendet.
Zeige mal die Definition der Task-Threads und vielleicht bisschen relevanten Code.
Anscheinend werden zwar da Handles geöffnet, aber nicht geschlossen.
Was passiert in den Tasks?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Handle count erhöht sich permanent

  Alt 22. Okt 2014, 12:10
Warum keine TObjectList<T> mit OwnsObjects=True? (das Freigeben "fRunningTasks[i].Free;" macht die dann selber)

Das Erstellen von Threads geschieht im selben Thread, wie dein Löschen?
Wenn nicht, warum gibt es hier dann keine Syncronisierung/Threadabsicherung?

Was macht du in deinen Threads?
Wenn die Threads intern nichts machen (leeres Execute usw.), gehen die Handle dann auch noch hoch?
$2B or not $2B
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.771 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Handle count erhöht sich permanent

  Alt 22. Okt 2014, 12:12
Hallo TiGü,

ich hoffe der Code ist relevant genug.
Ich sehe darin nichts auffälliges..

Delphi-Quellcode:
  TThreadTask = class(TThread)
    protected
      procedure onTerminate(sender: TObject);
    private
      fDevice: TDevice;
      fTask: TTask;
      fLogger: TLogger;
    public
      constructor create(device: TDevice; task: TTask);
      destructor Destroy; override;
      procedure Execute; override;
  end;
Delphi-Quellcode:
constructor TThreadTask.create(device: TDevice; task: TTask);
begin
  inherited create(true);
  freeOnTerminate := false;
  fLogger := TLogger.instance;
  fDevice := TDevice.create;
  fDevice.id := device.id;
  fDevice.name := device.name;
  fDevice.powerSourceId := device.powerSourceId;
  fTask := task;
  inherited onTerminate := onTerminate;
end;
Delphi-Quellcode:
destructor TThreadTask.Destroy;
begin
  freeAndNil(fDevice);
end;
und die Execute Routine

Delphi-Quellcode:
procedure TThreadTask.Execute;
begin
if assigned(fDevice) then
  begin
    case fTask of
      powerState: begin
                    try
                      fDevice.getDevicePowerState; //snmp Abfrage
                      case fDevice.powerState of
                        true: fLogger.add(6,format('Scan finished for: <%s - %s>',[fDevice.name, 'on']));
                        false: fLogger.add(6,format('Scan finished for: <%s - %s>',[fDevice.name, 'off']));
                      end;
                    except
                      on E: Exception do
                        begin
                          fLogger.add(1,format('Error in power-state query: %s',[E.Message]));
                        end;
                    end;
                  end;
      powerOn: begin
                 try
                   fDevice.powerOn;
                 except
                   on E: Exception do
                     fLogger.add(1,format('Error in power-on operation: %s',[E.Message]));
                 end;
               end;
      powerOff: begin
                  try
                    fDevice.powerOff;
                  except
                    on E:Exception do
                      fLogger.add(1,format('Error in power-off operation: %s',[E.Message]));
                  end;
                end;
    end;
  end;
end;
Klaus
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.771 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Handle count erhöht sich permanent

  Alt 22. Okt 2014, 12:19
Das Erstellen von Threads geschieht im selben Thread, wie dein Löschen?
Wenn nicht, warum gibt es hier dann keine Syncronisierung/Threadabsicherung?

Was macht du in deinen Threads?
Wenn die Threads intern nichts machen (leeres Execute usw.), gehen die Handle dann auch noch hoch?
Der ThreadTask wird ausserhalb erstellt
und der TaskListe im Threadpool hinzugefügt.
Der ThreadTask wird suspended erstellt.

Delphi-Quellcode:
function TThreadpool.addTask(task: TThreadTask): Boolean;
begin
  fCriticalSection.Acquire;
  result := false;
  if fTaskList.Count < fMaxTaskList then
    begin
      fTaskList.Add(task);
      result := true;
    end;
  fCriticalSection.Release;
end;
Im Threadpool wird der ThreadTask dann gestartet, wenn ein Platz in fRunningTasks frei ist.

Auch wenn der Threadtask nichts ausführt, erhöht sich die Anzahl der Handles wie vorher auch.

Grüße
Klaus
Klaus

Geändert von Klaus01 (22. Okt 2014 um 12:36 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Handle count erhöht sich permanent

  Alt 22. Okt 2014, 12:32
Zitat:
Der ThreadTask wird ausserhalb erstellt
Und wo ist dann die fCriticalSection, beim Durchlaufen und vorallem Löschen der Items?

Wie gesagt, wenn du im Constructor und Execute deinen Code mal auskommentierst, bleiben dann die Handle gleich?




Bezüglich deinem komischen OnTerminate-Konstrukt:
Delphi-Quellcode:
protected
  procedure DoTerminate; override;

procedure TThreadTask.DoTerminate;
begin
  inherited;
  ...
end;

// bzw., wenn der Code im Hauptthread ausgeführt werden soll (OnTerminate wird ja auch synchronisiert)

procedure TThreadTask.DoTerminate;
begin
  inherited;
  Synchronize(procedure
    begin
      ...
    end);
end;
$2B or not $2B
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.771 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Handle count erhöht sich permanent

  Alt 22. Okt 2014, 12:53
Zitat:
Der ThreadTask wird ausserhalb erstellt
Und wo ist dann die fCriticalSection, beim Durchlaufen und vorallem Löschen der Items?

Wie gesagt, wenn du im Constructor und Execute deinen Code mal auskommentierst, bleiben dann die Handle gleich?
Brauche ich beim Löschen eine CriticalSection?
fRunningTasks ist eine Liste die nur im Threadpool existiert.

Die TaskList ist eine Liste die von aussen befüllt wird.
Dort sind "geparkten" ThreadTasks enthalten.

Aus der TaskListe werden die ThreadTasks in die fRunningTaskliste verschoben und anschließend gestartet.
Gut beim Verschieben aus der TaskList in die fRunningTasks Liste, da könnte eine criticalSection fehlen.

Den onTerminate Konstrukt werde ich mir nochmals anschauen.

Wenn der Excute-code leer ist erhöht sich die Anzahl der Handles auch.
Auch wenn der Constructor leer ist, erhöht sich die Anzahl der Handles.

Grüße
Klaus
Klaus

Geändert von Klaus01 (22. Okt 2014 um 14:29 Uhr)
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.477 Beiträge
 
Delphi 12 Athens
 
#8

AW: Handle count erhöht sich permanent

  Alt 22. Okt 2014, 13:03
destructor TThreadTask.Destroy;

Fehlt da nicht ein "inherited"?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Handle count erhöht sich permanent

  Alt 22. Okt 2014, 13:51
Fehlt da nicht ein "inherited"?
Ja.
$2B or not $2B
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.771 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Handle count erhöht sich permanent

  Alt 22. Okt 2014, 14:28
sodele..

ich habe nun das komische onTerminate Konstrukt abgeändert
und das fehlende inherited in der Destroy-Methode hinzugefügt.

.. und es schaut sehr viel besser aus.
Es wird die Anzahl der Handles nur um 1 pro Durchlauf erhöht.
.. das werde ich dann auch noch finden.

Danke für die Hilfe.

Grüße
Klaus
Klaus
  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 23:40 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