AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Thread.Queue, Zeitmessung, Thread hängt angeblich
Thema durchsuchen
Ansicht
Themen-Optionen

Thread.Queue, Zeitmessung, Thread hängt angeblich

Ein Thema von AJ_Oldendorf · begonnen am 20. Mai 2025 · letzter Beitrag vom 23. Mai 2025
Antwort Antwort
Seite 5 von 8   « Erste     345 67     Letzte »    
Kas Ob.

Registriert seit: 3. Sep 2023
431 Beiträge
 
#41

AW: Thread.Queue, Zeitmessung, Thread hängt angeblich

  Alt 21. Mai 2025, 13:42
Ich versuche auf einige Fragen zu antworten aber das Senden mit UDP hin und her mit softwareseitiger Quittierung funktioniert ja. OHNE VCL Hänger.
Der UDPServer ist ein Thread und empfängt die Daten.
Für jeden UDP Teilnehmer im Netzwerk (=Client), erzeuge ich mir im Server einen eigenen Thread, der dann das Senden an den Client übernimmt (dieser heißt bei mir Client-Thread und ist natürlich ein TThread).
Das Senden macht NICHT der Server-Thread direkt. Der Server gibt dem Client-Thread nur die Hostadresse und Port (vom Empfang) mit.
Im Client-Thread wird ein IdUDPClient erstellt, welcher das Senden übernimmt an Host und Port. Der Client-Thread überwacht auch selber die Quittierung der UDP Telegramme. Daher braucht sich die Server-Komponente NUR um den Empfang kümmern.
Der Datenaustausch mit dem Client-Endgerät, wird durch einen Client-Thread gemacht.
Der Client-Thread überwacht seine MessageQueue mit besagter PeekMessage-Technik und wenn für eine gewisse Zeit, keine Daten mehr eintreffen, wird der Teilnehmer als offline erkannt und der Client-Thread terminiert sich mit ".Terminate"
IdUDPClient is a component, did you assign an owner for it ? if yes then this might explain a lot.

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.
Kas
  Mit Zitat antworten Zitat
AJ_Oldendorf

Registriert seit: 12. Jun 2009
473 Beiträge
 
Delphi 12 Athens
 
#42

AW: Thread.Queue, Zeitmessung, Thread hängt angeblich

  Alt 21. Mai 2025, 14:14
IdUDPClient liegt auf einem Datenmodul welches mit .Create(Nil); erzeugt wird.
Also nein, es hat keinen Owner.

Das Senden mit IdUDPClient sieht so aus:
Delphi-Quellcode:
IdUDPClient.SendBuffer(MyDModul.IdUDPClient.Host,
                       MyDModul.IdUDPClient.Port,
                       ByteMsg);
Eine Prüfung genau an dieser Stelle auf "MainThreadID" und "GetCurrentThreadID" sagt auch, KEIN VCL Kontext.

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.
  Mit Zitat antworten Zitat
Edelfix

Registriert seit: 6. Feb 2015
Ort: Stadtoldendorf
247 Beiträge
 
Delphi 12 Athens
 
#43

AW: Thread.Queue, Zeitmessung, Thread hängt angeblich

  Alt 21. Mai 2025, 14:28
Weil ich Indy sehe muss ich an TIdAntiFreeze denken.

Bin mir aber nicht sicher ob das an dieser Stelle hilfreich ist.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Thread.Queue, Zeitmessung, Thread hängt angeblich

  Alt 21. Mai 2025, 14:49
Aber nur wenn man es im Hauptthread verwendet, was hier ja wohl nicht vorkommt.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Kas Ob.

Registriert seit: 3. Sep 2023
431 Beiträge
 
#45

AW: Thread.Queue, Zeitmessung, Thread hängt angeblich

  Alt 21. Mai 2025, 15:13
IdUDPClient liegt auf einem Datenmodul welches mit .Create(Nil); erzeugt wird.
Also nein, es hat keinen Owner.

Das Senden mit IdUDPClient sieht so aus:
Delphi-Quellcode:
IdUDPClient.SendBuffer(MyDModul.IdUDPClient.Host,
                       MyDModul.IdUDPClient.Port,
                       ByteMsg);
Eine Prüfung genau an dieser Stelle auf "MainThreadID" und "GetCurrentThreadID" sagt auch, KEIN VCL Kontext.

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.
Saying killing so many threads at once can cause this, make my sad.
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:
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.
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.

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.
Kas
  Mit Zitat antworten Zitat
Kas Ob.

Registriert seit: 3. Sep 2023
431 Beiträge
 
#46

AW: Thread.Queue, Zeitmessung, Thread hängt angeblich

  Alt 21. Mai 2025, 15:20
Aber nur wenn man es im Hauptthread verwendet, was hier ja wohl nicht vorkommt.
I am pretty much sure it is the main thread problem to begin with, as UDP server is most likely a dropped component on a form or module, this one is creating the socket and listening to the traffic then later another TIdUDPClient form different thread is creating socket and trying to perform recv from the same address, leaving them both competing on shared resource.

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 ...
Kas
  Mit Zitat antworten Zitat
AJ_Oldendorf

Registriert seit: 12. Jun 2009
473 Beiträge
 
Delphi 12 Athens
 
#47

AW: Thread.Queue, Zeitmessung, Thread hängt angeblich

  Alt 22. Mai 2025, 05:55
Zitat:
Saying killing so many threads at once can cause this, make my sad.
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):
Ich habe nicht verstanden, was mir das Beispiel helfen soll.
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:
I am pretty much sure it is the main thread problem to begin with, as UDP server is most likely a dropped component on a form or module, this one is creating the socket and listening to the traffic then later another TIdUDPClient form different thread is creating socket and trying to perform recv from the same address, leaving them both competing on shared resource.

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 ...
Ich dachte alle Fragen beantwortet zu haben aber hier nochmal zur Klarstellung.
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

Geändert von AJ_Oldendorf (22. Mai 2025 um 05:58 Uhr)
  Mit Zitat antworten Zitat
shebang
Online

Registriert seit: 7. Feb 2020
147 Beiträge
 
Delphi 11 Alexandria
 
#48

AW: Thread.Queue, Zeitmessung, Thread hängt angeblich

  Alt 22. Mai 2025, 08:10
Wie kann ich in meinem Programm selbstständig feststellen, wer die VCL blockieren könnte bzw was der VCL Thread aktuell macht.
Du lässt das Programm im Debugger laufen und während des VCL Hängers pausiert du den Debugger. Aus der Threadliste suchst du dir dann den VCL Thread heraus und guckst dir im Stacktrace an, in welcher Funktion er steckt. Je nachdem was er gerade macht, musst du das ein paar mal wiederholen.
  Mit Zitat antworten Zitat
Kas Ob.

Registriert seit: 3. Sep 2023
431 Beiträge
 
#49

AW: Thread.Queue, Zeitmessung, Thread hängt angeblich

  Alt 22. Mai 2025, 08:55
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.

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
Same as my first post in this thread, use a profiler and it will pin point the long VCL operation.

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:
IdUDPClient liegt auf einem Datenmodul welches mit .Create(Nil); erzeugt wird.
Also nein, es hat keinen Owner.
It could be something missed in translation.

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.
Kas
  Mit Zitat antworten Zitat
AJ_Oldendorf

Registriert seit: 12. Jun 2009
473 Beiträge
 
Delphi 12 Athens
 
#50

AW: Thread.Queue, Zeitmessung, Thread hängt angeblich

  Alt 22. Mai 2025, 09:33
Zitat:
Du lässt das Programm im Debugger laufen und während des VCL Hängers pausiert du den Debugger. Aus der Threadliste suchst du dir dann den VCL Thread heraus und guckst dir im Stacktrace an, in welcher Funktion er steckt. Je nachdem was er gerade macht, musst du das ein paar mal wiederholen.
Danke, dass werde ich versuchen.

Zitat:
Same as my first post in this thread, use a profiler and it will pin point the long VCL operation.
Ich wollte es gerne nach Möglichkeit gerne selber erkennen und keine Fremdsoftware dafür installieren.

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
Ich habe es auch ohne Datenmodul versucht und die UDPClient Komponente als Variable im Threadobjekt deklariert. Das hat kein Unterschied ausgemacht. Liegt also nicht daran.

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 Ich sage nur, wie ich es erzeugen kann, woran es tatsächlich liegt, suche ich ja noch
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 5 von 8   « Erste     345 67     Letzte »    


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 10:04 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