![]() |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
IN all cases IdUDPClient is overkill as i explained the from that initial event fired on server side you already have the connection (what called a distinguish identifier for UDP client) along a way to send using SendTo, so introducing IdUDPClient triggering threads that is competing with the server over this connection, is an overhead approach. Now about that last line, your timeout at 250ms monitoring messages is to switch between 1) check if a message is received then what, either timed out at 250ms which contradict the need for real time or 2) try to read from the client ? or send ? Still the whole design is not clear. Just handle the packets in the one recv thread then send from it, even if it is the server triggered event OnRead, because there is something is triggering the main thread to perform some work (a lot of work), and even after all what did you described, this doesn't explain the main thread business. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
IdUDPClient liegt auf einem Datenmodul welches mit
Delphi-Quellcode:
erzeugt wird.
.Create(Nil);
Also nein, es hat keinen Owner. Das Senden mit IdUDPClient sieht so aus:
Delphi-Quellcode:
Eine Prüfung genau an dieser Stelle auf "MainThreadID" und "GetCurrentThreadID" sagt auch, KEIN VCL Kontext.
IdUDPClient.SendBuffer(MyDModul.IdUDPClient.Host,
MyDModul.IdUDPClient.Port, ByteMsg); Das Thema mit den 250ms ist in dem Verarbeitungsthread, hat nichts mit dem Client-Thread zu tun! Das Thema sollten wir nicht weiter betrachten. Richtig, dass Hauptproblem ist nach wie vor die hängende VCL für ~ 7s. Interessant ist, es sind wirklich immer ~ 7s, bei jedem Test. Gibt es eine Möglichkeit, dass ich selber herausbekomme, was der VCL Kontext/Thread gerade gemacht? Ich glaube nämlich nicht, dass das UDP Thema damit eine Rolle spielt. Ich kann es nur dadurch erzeugen, da ich damit so viele Threads gleichzeitig beende. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Weil ich Indy sehe muss ich an TIdAntiFreeze denken.
Bin mir aber nicht sicher ob das an dieser Stelle hilfreich ist. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Aber nur wenn man es im Hauptthread verwendet, was hier ja wohl nicht vorkommt.
|
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Here a simple test that will create 50000 threads and exits them, no killing just exit gracefully, creating them in fraction of second and exit them in second(s):
Delphi-Quellcode:
Build it for 64bit not 32bit, and don't run it in the debugger as it will kill the IDE, try to increase the created and exited threads to 100k, will there be a big difference.
unit Unit10;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls; type TForm10 = class(TForm) Timer1: TTimer; Label1: TLabel; Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Timer1Timer(Sender: TObject); private procedure CreateOneThread; procedure CreateThreads(Count: Integer); public { Public declarations } end; var Form10: TForm10; implementation {$R *.dfm} var CurrentThreadCount: Integer; const CREATE_MANY_THREADS = 50000; THREADS_STACK_SIZE = 64 * 1024; STACK_SIZE_PARAM_IS_A_RESERVATION = $00010000; function ThreadFunc(Parameter: Pointer): Integer; begin InterlockedIncrement(CurrentThreadCount); Sleep(4000); InterlockedDecrement(CurrentThreadCount); EndThread(0); end; procedure TForm10.FormCreate(Sender: TObject); begin Timer1.Interval := 50; end; procedure TForm10.CreateOneThread; var ThreadId: Cardinal; ThreadHandle: THandle; begin ThreadHandle := BeginThread(nil, THREADS_STACK_SIZE, Addr(ThreadFunc), 0, STACK_SIZE_PARAM_IS_A_RESERVATION, ThreadId); if ThreadHandle <> 0 then CloseHandle(ThreadHandle); end; procedure TForm10.CreateThreads(Count: Integer); begin while Count > 0 do begin CreateOneThread; Dec(Count); end; end; procedure TForm10.Button1Click(Sender: TObject); begin if IsDebuggerPresent then CreateThreads(10) else CreateThreads(CREATE_MANY_THREADS); end; procedure TForm10.Timer1Timer(Sender: TObject); begin Label1.Caption := IntToStr(CurrentThreadCount); end; end. Anyway all Indy components are tied internally to singletons that track their creation and lifetime, using CciticalSection and try to look for singleton that protect from hanging and freezing also for logging...etc.. I am not expert on Indy but you approach even with 35 connection is wrong and cause this. Away from that there is no solution like put this line and it will work fine. ps: when running that test of 50k threads watch the red against the green in Process Explorer. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
The question AJ_Oldendorf did not answer, are there any sort of Synchronize or Thread control functions/method from "TThread." being used ? is there from TThread beyond Create and Execute being used ? like WaitFor ... |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Es geht bei mir um 35 Threads, nicht um 50000. Meine Threads sind Objekte vom Typ TThread und werden mit TThread.Create() erstellt. Warum sind es 35 einzelne Threads mit jeweils einer UDPClient Komponente? Jeder Thread und jeder Teilnehmer, kann zu unterschiedlichen Zeiten unterschiedliche Daten geschickt bekommen. Wird alles in einem Thread abgewickelt wird, müssen sich alle Telegramme durch eine UDPClient-Komponente quälen, so kann jeder Thread an seinen jeweiligen Empfänger (dies ist natürlich auch immer ein anderer, also 35 verschiedene Empfänger) losgelöst arbeiten. Zitat:
Es wird kein Synchronize im Programm verwendet. Es wird kein WaitFor... im Programm verwendet. Class functions/method von "TThread." (wie TThread.Queue) wird nicht verwendet. Ich habe reine Variablen/Objekte vom Typ TThread und die werden mit .Create erstellt und nur über den Variablennamen darauf zugegriffen. Ich möchte nochmal auf das Hauptproblem zurück kommen. VCL Hänger. Wie kann ich in meinem Programm selbstständig feststellen, wer die VCL blockieren könnte bzw was der VCL Thread aktuell macht. Vielleicht wird ja auch aus irgendeinen unbekannten Grund, eine rechenintensive Funktion durch den VCL Thread bearbeitet, was natürlich auch den Hänger erklären würde |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
|
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
That example shows how threads are magnificent beasts on Windows, 50k are feather light in creating and exiting, (notice it might be translation problem as i read killing threads), yet it takes only 4 on my 4-core CPU to destroy my whole OS experience, the example is to show you you are after the wrong reason, creating and exiting threads is fast.
Zitat:
See you insist on creating one UDPClient per connection on a server, that is wrong, you said you are not assigning and owner, yet in the same phrase they are on DataModule Zitat:
My final words here is, there is no unknown reason for this, there is broken logic and false assumptions, so no, not Windows faults, not network adapter faults, and not Delphi RTL/VCL fault. Remove the UDPClient creation, make sure you are not creating TDataModule with punch of components on it per client, simplify the logic into one thread per one client doing it all and this freeze will disappear. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Zitat:
Zitat:
Ich sage auch nicht, dass Beenden von Threads generell lange dauert. Das wäre sicherlich schon jemanden vor mir aufgefallen, wenn es denn so wäre :-D Ich sage nur, wie ich es erzeugen kann, woran es tatsächlich liegt, suche ich ja noch |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:06 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