![]() |
Thread Vs Timer !!! Wievile Threads sind zu viel ?
Hi Leute,
ich sitze gerade an einem Prog, das ne ganze Menge im Hintergrund macht und genauso viel im Vordergrund. Ich habe im Moment : 4 Timer 12 Threads einen IdHttp-Server, der natürlich auch ein paar Threads aufmacht ;-) einen IdTcpServer, der ebenfalls mehere Threads erzeugt 2 x TWebBrowser, die komischerweise jeweils 4 Threads erzeugen, warum :gruebel: Wenn ich jetzt meine App starte sehe ich im Task-Manager, das um die 30 Threads dazu kommen, ist das schon hart an der Grenze ? Meine App läuft normalerweise mit 5-8 % CPU-Last, aber neuderdings von Zeit zu Zeit(also absolut sporadisch) steigt die CPU-Last auf 98 % und legt alles lahm. Das führt mich zu der Frage soll ich aus den Threads Timer machen bzw. aus den Timern Threads ?! Ok, Timer sind ungenau ! Aber haben Threads die höhere Systembelastung ? Im Moment verwende ich die Timer für die absolut "unwichtigen" regelmäßigen Aufgaben z.B. Server pingen, um "Ich bin noch da" zu sagen. Und für die Aufgaben wo es um Geschwindigkeit geht Threads, die teilweise alle 50 ms agieren. Aber zurück zum Themaq : Alles Threads oder Alles Timer ??? Gruß Data P.S. Wenn ich nur Timer verwende, wird das OnTimer-Ereignis jedesmal vom Main-Thread mit syncronize aufgerufen ? |
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Auf was für eienm System soll das ganze Laufen? Für Consumer Windows könnte es schon kritisch werden.
Was die CPU Last angeht: So lange deine Threads Rechenzeit abgeben, wenn sie von anderen Prozessen gebraucht wird, ist alles in Ordnung. Warum sollen sie nicht 98% der CPU Zeit nutzen. Lass sie arbeiten, dafür hast du sie gekauft. Welche Priorität haben deine Threads? Was sich auch günstig auswirkt ist eien Sleep(0) am Ende jeder Threadschleife, dadurch geben sie nicht mehr benötigte Rechenzeit freiwillig ab. Die Timer im primären Thread mußt / kannst du nicht synchronisieren. Desweiteren würde ich dir raten auf Threads umzusteigen, da Timer deine Anwendung immer lahm legen, so lange das Timer Ereigniss abgearbeitet wird. Und wichtig: Immer synchronisieren entweder mit der Synchronize-methode des Thread-Objektes, CriticalSections oder atomare Funktionen wie die InterLockedExchange Funktionen. |
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Hi Luckie,
die App soll auf alle noch gängigen Windows-Systemen laufen, auch Win98 u. WinME. Zu den Threads : Die meisten laufen im Hintergrund mit normaler bzw. niedriger Priorität und sollen nur in Intervallen a 60 bzw. 75 Sek. einen Http-Request(auch mit Indy) absetzen und anhand der Antwort Gui-Elemente aktualisieren, was ich auch mit Syncronize mache. Hier mal ein Beispiel wie dir meisten meiner Threads ablaufen ;
Code:
Was mich nur wundert bzw. ärgert :
procedure TAdminListThread.Execute;
Var iWait : Longint; begin while not Terminated do begin DoRequest; // iWait := 0; // cIntervall ist in diesem Fall 75000 While (not Terminated) and (iWait < cIntervall) do begin inc(iWait,500); sleep(500); end; end; end; Bis vor kurzem hatte ich eine Version die einwandfrei lief und auch unter extremer Belastung nur max. 20% der CPU ausgelastet hat. Dann habe ich wirklich nur ein paar Kleinigkeiten geändert, so unrelevate Sachen das ich die Änderungen nicht mal mehr aufzählen kann :oops: Ich glaube ich habe einen Intervall von 140000 Sek. auf 120000 Sek geändert, zwei Timer auf Formulare gesetzt, die ich nur dynamisch erzeuge und danach wieder freigebe. Und zwei drei andere Kleinigkeiten die mir aber nicht mehr einfallen :oops: Das schlimme ist das ich normalerweise bei jeder Version/Release bevor ich sie hoch lade und den usern zur verfügung stelle, einmal komplett den Quellcode mit Version sichere. Das habe ich vor lauter Stress leider nicht getan, d.h. die letzte Version wo dieses Phänomen der CPU-Belastung nicht auftrat ist schon etwas älter :wall: Bei der ganzen App geht es um eine Live-Bildübertragung mit eingebauten Chat(deshalb die 2 TWebbrowser instanzen) Die hauptsächlichen Zeitkritischen Threads sind die beiden Bildübertragungsthreads : 1. Ein WebServer mit IdHttpServer 2. Ein normaler IdTcpServer beide greifen das Bild einer Webcam/Videokamera syncronisiert vom Video-Treiber ab. Dann gibt es noch zwei Timer die in Abständen von 100 ms folgendes tun : Der eine schickt geschriebene Chat-Texte, die erst in einer Stringlist zwischengespeichert werden, zu den Clients. Der andere Timer stellt die Erhaltenen Chat-Texte dar. Er erstellt davor einen lokalen HTML-File der dann vom TWebbrowser aufgerufen wird. Hat irgentjemand eine Idee, durch welche Umstände plötzlich eine solch schlechte Performance verursacht werden könnte ? Oder ist jemand im Decompilen und asm so gut, das er mir die UNterschiede von meiner alten und neuen App nennen kann ? Danke schonmal im vorraus für jede Hilfe, weiß gerade wirklich nicht weiter Data |
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Also die Anzahl sollte noch nicht so kritische sein. Windows 2k und höher ist ja auf Multithreading ausgelegt. Bei mir laufen meistens so 250 Threads insgesamt. Solange die nicht zuviel CPU Zeit verbraucht ist doch alles im grünen Bereich.
mfg |
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Windows 9x/ME ist auch auf Multithreading "ausgelegt" wie du es bezeichnest. Nur kann Windows9x/ME nicht so viele Ressourcen verwalten. das dein Windows2000 System 250 Threads verkraften kann, sagt nichts über Windows 9x/ME aus. das sind zwei total verschiedene Paar Schuhe.
|
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
bei mir laufen meistens 300-350 Threads und die cpu ist nicht belastet(Win XP Prog. 1.8 Ghz, 1 GB Ram)
Noch ne Frage zum Timer : Der Timer benutzt ja die WM_Timer Message, läuft das OnTimer-Ereigniss wirklich in einem seperaten Thread parallel zum Hauptthread ? Was schluckt mehr Ressourcen ein Thread mit Priorität tpLowest im vergleich zum Timer ? Data |
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Ein Timer funktioniert ja folgendermaßen: Wenn in der Nachrichtenschleife des Hauptfensters eine WM_TIMER-Nachricht auftritt, wird die Prozedur, auf die Timer.OnTimer zeigt, ausgeführt, und zwar in einem extra Thread.
Die Prozessorauslastung dürfte relativ gleich sein, der Unterschied ist eben, dass sich die WM_TIMER-Nachtichten sehr verzögern können, wenn du in einem Thread innerhalb des Programms einen Timer einsetzt, kannst du (fast) völlige Synchronisation erhalten. |
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Zitat:
Der TTimer erzeugt ein Fenster, welches die WM_TIMER Nachricht erhält. Diese Procedure wird nicht in einen extra Thread ausgeführt, sondern in dem Thread in dem sich der Timer befindet. Um Resourcen (Fenster-Handles und Speicher) zu sparen, verwende ich Timer nur über
Delphi-Quellcode:
SetTimer
KillTimer WM_TIMER |
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Ok, d.h. auf jeden Fall besser ein Thread mit niedriger Priorität verwenden als ein Timer.
So müßte die Belastung in etwa gleich seien, nur bei einem Thread kann ich mir sicher sein das es wirklich ein Thread ist und der Thread-Code wirklich "parallel" zum Haupt-Thread ausgeführt wird. Data |
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Ich hab zwar schon nonVCL-Anwendungen geschrieben, allerdings dort noch nie einen Timer verwendet.
Sehr komisch, ich hätte schwören können, dass die Berechnung in einem extra Thread abliefe. Anscheinend hat mich da mein Gedächtnis betrogen, aber ich hätte schwören können, dass der Prozess 2 Threads hat, sobald ich den Timer aktiviere. :oops: |
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Das kann sein das der Zusätzliche Thread durch SetTimer erzeugt wird, doch das dachte ich wäre ein SystemThread.
|
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Hab das mal getestet.
Bei mir (Win2k) gibt es keinen extra Thread bei Timer Einsatz. TIPP: Setzt mal einen Timer z.B. auf 2 sec. In der Timer-Proc (WM_TIMER) eine Message-Box zeigen und dann das verhalten studieren. Da sollte herauskommen das WM_TIMER eine normale Windowsnachricht ist. |
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Mit SetTimer wird an das aufrufende Fenster und somit an den primären Thread eine WM_TIMER Nachricht geschickt. Dies ist eine Nachricht, wie jede andere auch. Wo soll da der zweite Thread herkommen?
|
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Und hier mal ein
![]() Gruß Wormid |
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Hi Leute,
nochmal ne Frage zu dem Thema Threads : Wenn ich einen Thread habe der nur alle 60 Sek./60000 ms. eine Aktion durchführen soll, darf ich dann im Execute des Threads den Thread mit sleep für 60 sek. schlafen legen, oder muss ich z.B. jede Sekunde überprüfen, ob der Thread nicht beendet wurde. ich poste einfach mal zwei Code Beispiele, dann wid klar was ich meine : Code 1(jetziger Zustand) :
Delphi-Quellcode:
Code 2(wäre von der Performence/Systembelastung natürlich besser) :
procedure TmyThread.Execute;
Var iWait : Longint; begin While not Terminated do begin doRequest; iWait := 0; While (not Terminated) and (iWait < 60000) do begin inc(iWait,500); sleep(500); end; end; end;
Delphi-Quellcode:
Meine Befürchtung ist nur das bei Bsp. 2 im schlimmsten Fall beim Beenden der Applikation 60 Sek. darauf gewartet wird das der Thread mitbekommt das er sich beenden soll.
procedure TmyThread.Execute;
begin While not Terminated do begin doRequest; sleep(60000); end; end; Danke im vorraus, Data [edit=Daniel B]Delphi-Tags korrigiert. Mfg, Daniel B[/edit] |
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Das sleep(60000) sorgt dafür, dass der Thread nur alle 60 Sekunden zuteilungsfähig wird.
|
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Hi Luckie,
d.h. also ich muss bei der ersten Variante bleiben, oder was kann ich anders machen ? Gruß Data |
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Kommt drauf an. Wenn er nur alle 60 Sekunden was machen soll, dann reicht doch ein sleep(60000).
|
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Das ist schon klar,
bekommt der Thread aber trotzdem mit, das er beendet werden soll und verlässt die Execute Methode ? Angenommen Thread hat gerade das gemacht was er machen soll, bekommt jetzt den Sleep(60000) Befehl eine sek. später schliesse ich meine Applikation Bekommt der Thread das mit oder bleibt die Applikation solange hängen bis die 60 Sek. des Threads um sind ? Gleich noch ne Frage : Wenn der Thread im "Sleep" ist, kann ich in der Zeit trotzdem eine public Methode des Threads aufrufen ? (Die betrifft in keinster Weise die Execute Schleife) Danke, Data |
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Nein, wärend des des "sleeps" bekommt der Thread keine Rechenzeit, kann also nichts machen.
Wenn du den Prozess schließt, dann werden auch automatisch alle zugehörigen Thread-Objekte zerstört egal in welchem Zustand sie sind. |
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Hi Luckie,
aber ich kann den Thread mit suspend anhalten(wenn er gerade schläft) ? Na dann habe ich glaub ich mein Problem gefunden, warum meine App sporadisch sich mit der CPU-Last auf 98% hochschaukelt, wahrscheinlich kommt der Systemprocess nicht mehr mit dem Thread-Handling nach. Ich habe nämlich ca. 10-15 Threads immer am laufen, die wie oben in Bsp. 1 beschrieben vorgehen nur ist der Sleep-Intervall da bei 500 ms bzw. 200 ms. :oops: :oops: Danke, Data |
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Versuch es mal mit Events und WaitForSingleObject.
Erstelle mal ein Bsp. Interessiert mich gerade selber! Geduld! |
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Zitat:
|
Re: Thread Vs Timer !!! Wievile Threads sind zu viel ?
Delphi-Quellcode:
Das könnte dir Helfen...
type
TTimerThread = class(TThread) private hClose : Cardinal; public constructor Create; destructor Destroy; override; procedure CloseMe; procedure Execute; override; end; { TTimerThread } procedure TTimerThread.CloseMe; begin SetEvent(hClose); end; constructor TTimerThread.Create; begin inherited Create(false); hClose := CreateEvent(nil, true, false, nil) end; destructor TTimerThread.Destroy; begin CloseMe; // schleife beenden CloseHandle(hClose); inherited; end; procedure TTimerThread.Execute; var dw : Cardinal; begin repeat dw := WaitForSingleObject(hClose, 60000); if dw = WAIT_TIMEOUT then Windows.Beep(200, 200); // mache irgentwas until (dw = WAIT_OBJECT_0) or Terminated; // beendet end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:48 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