AGB  ·  Datenschutz  ·  Impressum  







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

Arbeiten mit TThreadList

Ein Thema von Captnemo · begonnen am 7. Aug 2013 · letzter Beitrag vom 25. Jun 2014
Antwort Antwort
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#1

AW: Arbeiten mit TThreadList

  Alt 7. Aug 2013, 13:08
... in dem eine vom Benutzer festgelegte Anzahl an Threads starten sollen
Daher kam meine Frage.
Genau genommen geht es darum, seriell angeschlossene Geräte abzufragen. Wieviele angeschlossen werde, dass wird vom User eingestellt. Es können also 3 aber auch 10 sein. Ich selbst begrenze die Anzahl nicht.
Die Anzahl der quasi parallel laufenden Threads sollte m.E. abhänging von der Anzahl der CPUs/der cores sein und nicht zwingend von der Anzahl der abzufragenden Geräte.

Grüße
Klaus
Also darüber brauche ich ganz sicher keine Sorgen machen. Zum einen werde niemals mehr als 12 Geräte angeschlossen (das ist in diesem Anwendungsfall mal absolut sicher), und zum anderen liefern die Geräte nur in Intervallen von 10 Sekunden Daten, evtl. sogar mit viel größeren Abständen.
Dem zur Folge für meine Zwecke völlig okay. Ich hab's grad mal mit 20 Threads auf einem 1 Prozessorsystem getestet und hatte 0,1% Auslastung. Laufen wird es nachher auf einem 8-Core-System.

[OT on]
Hey, danke für eurer Interesse. Aber mir ging es tatsächlich um die Frage, die schon im ersten Thread stand. Nicht darum, ob und warum man die Threadanzahl begrenzen sollte. Solche Diskussionen ziehen diesen Beitrag nur unnötig in die Länge und nützen am Ende keinem. Außerdem wären dafür noch ganz andere Informationen über den Sinn und Zweck des Programm und der Threads notwendig.

Jetzt aber nicht gleich beleidigt sein, okay

Daniel hatte es für mich mit seiner Antwort schon wie immer sehr treffend auf dem Punkt gebracht.

[OT off]
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Arbeiten mit TThreadList

  Alt 7. Aug 2013, 13:13
Daniel hatte es für mich mit seiner Antwort schon wie immer sehr treffend auf dem Punkt gebracht.
Wann hat der denn hier geantwortet?
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#3

AW: Arbeiten mit TThreadList

  Alt 7. Aug 2013, 18:40
Daniel hatte es für mich mit seiner Antwort schon wie immer sehr treffend auf dem Punkt gebracht.
Wann hat der denn hier geantwortet?
Oh mein Gott

Meinte natürlich dich Verd*mt, hab euch glatt verwechselt. Wie peinlich

Also, natürlich hast du es auf den Punkt gebracht. Großes Sorry
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo
  Mit Zitat antworten Zitat
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#4

AW: Arbeiten mit TThreadList

  Alt 23. Jun 2014, 12:24
Hi, ich muß diese Thema noch mal aufwärmen, da ich da noch ein paar Probleme habe.

Also ich erzeuge mir eine TThreadList, die ich beim Beenden des MainThread entfernen möchte.

Delphi-Quellcode:
procedure Tfrm_main.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
  I: Integer;
  r: Cardinal;
begin
  for I := RS232ThreadList.Count-1 downto 0 do
  begin
    TComThread(RS232ThreadList[i]).StopListen;
    TComThread(RS232ThreadList[i]).Terminate;
    r:=WaitForSingleObject(TComThread(RS232ThreadList[i]).Handle, 1000);
    //ShowMessage(IntToStr(r));
  end;
end;

procedure Tfrm_main.FormCreate(Sender: TObject);
begin
  RS232ThreadList:=TObjectList.Create;
end;

procedure Tfrm_main.FormDestroy(Sender: TObject);
begin
  RS232ThreadList.Free;
end;
Sicherlich nicht korrekt, denn im FormDestroy kommt es beim RS232ThreadList.Free zu einer Exception, da die Thread noch nicht beendet sind.

Bzw. genau genommen, lande ich in System.Classes im Destructor TThread.Destroy beim CloseHandle;
Meine Annahme, die Threads in der ThreadList sind noch nicht beendet.

Wie mache ich es richtig? Ich muß ja im OnCanClose auf das Beenden der Threads warten.
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.041 Beiträge
 
Delphi 12 Athens
 
#5

AW: Arbeiten mit TThreadList

  Alt 23. Jun 2014, 12:43
Zeig mal

a) wie du die Threads erzeugst (FreeOnTerminate?)
b) wie du die Liste erzeugst (OnwsObjects?)
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#6

AW: Arbeiten mit TThreadList

  Alt 23. Jun 2014, 13:01
Wieso wartest Du nur maximal eine Sekunde auf das Handle? Warte doch lieber, bis das Handle die Fahne oben hat, auch wenn's dauert...
Und falls es sich dabei um Threads handelt, würde ich mit 'WaitFor' noch warten, bis das Teil auch wirklich beendet ist und es dann ggf. explizit per Free freigeben (außer, das macht die ThreadListe selbst)
  Mit Zitat antworten Zitat
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#7

AW: Arbeiten mit TThreadList

  Alt 23. Jun 2014, 13:29
Mit OwnObject:=False funktionierts. FreeOnTerminate ist True.

Jetzt werden die Objecte (Thread) also freigegen, wenn die Liste freigegeben werden.
Aber eigentlich müßte es ja auch anders gehen.

Ist denn das mit Waitforsingleobject so korrekt? Was ist eigentlich der Rückgabewert von Waitforsingleobject? In meinem Fall habe ich immer 0 zurück bekommen.

Das mit 1000 Milisekunden ist erst mal zum Testen gewesen.

Mit WaitFor on OnCanClose bekomme ich immer die EThread-Exception "Das Handle ist ungültig(6)".
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo
  Mit Zitat antworten Zitat
Der schöne Günther
Online

Registriert seit: 6. Mär 2013
6.112 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Arbeiten mit TThreadList

  Alt 23. Jun 2014, 13:51
Das ist die TThreadList aus System.Classes oder System.Generics.Collections , oder? Ich kann der nichts abgewinnen: Da fehlen elementarste Dinge wie ein GetEnumerator() und alles. Bist du sicher, dass du die brauchst? Ich hätte gedacht, dass du die RS232-Threads alle im Hauptthread erstellst und an die Liste dranhängst und ebenso dort auch die Liste wieder zumachen willst?

Ich nehme da einfach eine ganz "normale" Objektliste (TObjectList )- Soweit die OwnsObjects = True hat, ist die Freigabe der Liste mitsamt aller enthaltenen Threads so einfach wie ein meineListe.Free(); Bsp:
Delphi-Quellcode:
program Project4;

{$APPTYPE CONSOLE}
{$R *.res}

uses
   System.SysUtils,
   System.SyncObjs,
   System.Classes,
   System.Generics.Collections;

const
   numThreads: Integer = 5;

var
   threadList: TObjectList<TThread>;
   threadNum: Integer;
   threadIterator: TThread;
   consoleCs: TSynchroObject;

//{$DEFINE OWNSOBJECTS}

procedure writeConsole(const line: String);
begin
   consoleCs.Acquire();
   try
      WriteLn(line);
   finally
      consoleCs.Release();
   end;
end;

function constructRunningThread(const threadNum: Integer): TThread;
begin
   Result := TThread.CreateAnonymousThread(
      procedure
      begin
         writeConsole('Thread ' + threadNum.ToString() + ' startet...');
         sleep(1000 + Random(4000));
         writeConsole('Thread ' + threadNum.ToString() + ' endet...');
      end
   );
   Result.FreeOnTerminate := {$IFDEF OWNSOBJECTS}False{$ELSE}True{$ENDIF};
   Result.Start();
end;

begin
   try
      consoleCs := TCriticalSection.Create();

      writeConsole('Erstelle und fülle Liste...');
      threadList := TObjectList<TThread>.Create(
         {$IFDEF OWNSOBJECTS}True{$ELSE}False{$ENDIF}
      );
      for threadNum := 0 to Pred(numThreads) do
         threadList.Add(constructRunningThread(threadNum));

      writeConsole('Baue Liste ab...');
      threadList.Destroy();
      writeConsole('Liste abgebaut');
      writeConsole('<Taste drücken>');
   except
      on E: Exception do
         WriteLn(E.ClassName, ': ', E.Message);
   end;

   ReadLn;
end.


// Roter Kasten:
Entweder ein TThread hat FreeOnTerminate = True und du fasst ihn nach dem Starten nicht mehr an(!) oder er hat es auf False und du gibst die TThread-Instanz selbst so frei wie du möchtest. Ich habe das mal versucht in das Beispiel zu packen: Du kannst das {$DEFINE OWNSOBJECTS} einmal auskommentieren und dir den Unterschied anschauen
  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 08:09 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