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 26. Mai 2025
Antwort Antwort
Seite 1 von 2  1 2      
AJ_Oldendorf

Registriert seit: 12. Jun 2009
486 Beiträge
 
Delphi 12 Athens
 
#1

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

  Alt 21. Mai 2025, 12:17
Zitat:
Thank you and well i think we are getting somewhere,
This raise few questions why to mention UDPClient here ? what are their proposes on server side ? if you are responding then use SendTo from the server Binding/Handler to get better idea refer to this example
https://github.com/tinydew4/indy-pro...ServerMain.pas

May be your server doesn't use UDPCLient and this miss understanding on me (translation or something) we get to different problematic approach THE loop
here how to do loop and handle thread messages
https://stackoverflow.com/questions/...ultipleobjects
https://devblogs.microsoft.com/oldne...17-00/?p=36423
Read the question and answers on SO also all the comments there, specially this one

Verstehe das Problem nicht. Ich rufe doch PeekMessage in einer While Schleife auf, so wie in dem verlinkten Beitrag.


Zitat:
Great, now explain how these are tied to MainThread, are these are the cause or
Verarbeitungsthread Anzahl 1..35 = Thread Nummer 37..71

Either group causing the main thread to block in waiting state, this behaviour red color on CPU usage unless you are not performing IO operations (reading/writing to disk or network in tight loop) then means one thing, high thread contention and main thread is not couping with it jumping from one place to another and have no time to process Messages.

Capture the culprit, try to exit either group before performing this sudden close, see what is wrong and change that timeout at 250ms to something useful like 30seconds (30000ms), you are not expecting messages that much after all.
Can you disconnect all the clients at once form server ? what happen ? etc...
Es werden nur die UDPClient-Threads beendet mit Terminate. Die Verarbeitungsthread (Anzahl 1..35 = Thread Nummer 37..71) laufen ganz normal weiter aber bekommen keine Daten von den UDPClient-Threads mehr, da diese beendet wurden. Es gibt allerdings noch andere Threads im Programm, welche den Verarbeitungsthreads weiterhin Daten schicken können, deswegen werden diese auch nicht beendet. Doch, die 250ms brauche ich, da ich eine echtzeitnahe Anwendung betreibe und sehr viele Daten mit den Threads austausche. Bitte keine Diskussion über Echtzeitnah, ich weiß, dass dies unter Windows nicht geht. Darum geht es hier auch nicht.

Ich trenne die UDPClients gleichzeitig! und genau dann tritt das Problem auf.
Trenne ich nur EINEN Client, passiert das Problem NICHT.
  Mit Zitat antworten Zitat
Kas Ob.

Registriert seit: 3. Sep 2023
457 Beiträge
 
#2

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

  Alt 21. Mai 2025, 12:56
Es werden nur die UDPClient-Threads beendet mit Terminate. Die Verarbeitungsthread (Anzahl 1..35 = Thread Nummer 37..71) laufen ganz normal weiter aber bekommen keine Daten von den UDPClient-Threads mehr, da diese beendet wurden. Es gibt allerdings noch andere Threads im Programm, welche den Verarbeitungsthreads weiterhin Daten schicken können, deswegen werden diese auch nicht beendet. Doch, die 250ms brauche ich, da ich eine echtzeitnahe Anwendung betreibe und sehr viele Daten mit den Threads austausche. Bitte keine Diskussion über Echtzeitnah, ich weiß, dass dies unter Windows nicht geht. Darum geht es hier auch nicht.

Ich trenne die UDPClients gleichzeitig! und genau dann tritt das Problem auf.
Trenne ich nur EINEN Client, passiert das Problem NICHT.
Still missing the point, what are UDPClient-Threads ?

Are they TThread ?
and more important question
Are you using a UDPClient or TIdUDPClient on server part ?

And more importanter then grammar is When you say 250ms is needed ....... WHYYYYYY

What are those thread suppose to do ? Send and/or receive or processing too ? are you piling jobs on threads and for that you need them to wait for 250ms then do another thing ? that is wrong and contradict the point of using threads to begin with.

When you say you have threads to received on the that event then that event is the one coming form dedicated thread allocated by Indy library to handle you recv and send, then use UDP server to send, and in that event just recv/read and utilize its parameter in that even to send when finished, this can be from any other threads (literally from anywhere).

explain in plain text the logic from receiving a packet to send it, do it on paper and you will find the root of these hugs.

Again refer to https://github.com/tinydew4/indy-pro...ServerMain.pas
Delphi-Quellcode:
procedure TUDPMainForm.UDPServerUDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
var
  DataStringStream: TStringStream;
  s: String;
begin
  DataStringStream := TStringStream.Create('');
  try
    DataStringStream.CopyFrom(AData, AData.Size);
    UDPMemo.Lines.Add('Received "' + DataStringStream.DataString + '" from ' + ABinding.PeerIP + ' on port ' + IntToStr(ABinding.PeerPort));
    s := 'Replied from ' + UDPServer.LocalName + ' to "' + DataStringStream.DataString + '"';
    ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, s[1], Length(s));
  finally
    DataStringStream.Free;
  end;
end;
Do send using "ABinding: TIdSocketHandle" "ABinding.SendTo" from anywhere, in other words no dedicated thread, to duck rubber explain it,
having TIdUDPServer on your application/server will remove the need for threads to receive and send, leaving one group of threads, the processing, you want to dedicate one per client ? ok that is fine, now i want you to question the existence of two group of threads, and explain them.

I am sure you miss understanding one functionality somewhere.
Kas
  Mit Zitat antworten Zitat
Kas Ob.

Registriert seit: 3. Sep 2023
457 Beiträge
 
#3

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

  Alt 21. Mai 2025, 13:02
Receiving from UDP is or can be blocking and can be non blocking, you really don't need to dedicate a thread per identified connection, just recv/read and pass to a thread then write/send from anywhere.

simplify the the groups need and keep only one, also if you like loop like that then wait on call and block on recv then handle then send, loop again, this will even simplify the things further, removing the need to pass data between threads altogether.
Kas
  Mit Zitat antworten Zitat
Kas Ob.

Registriert seit: 3. Sep 2023
457 Beiträge
 
#4

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

  Alt 21. Mai 2025, 13:12
One more thing to understand, that you might be missing,

UDP is unlike TCP, in case of TCP you can not send without checking the socket is ready to write/send, well you can but it might fail with error and ask you to block or to wait, UDP it is ready always, like always always, just SendTo and call it a day, it might fail or drop the packet but you don't have control about it as there is nothing to do about it, will not explain how to mitigate this here as it is irrelevant your case, 35 clients unless the traffic is saturating you connection it will work like charm.
Kas
  Mit Zitat antworten Zitat
AJ_Oldendorf

Registriert seit: 12. Jun 2009
486 Beiträge
 
Delphi 12 Athens
 
#5

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

  Alt 21. Mai 2025, 13:25
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"
  Mit Zitat antworten Zitat
Kas Ob.

Registriert seit: 3. Sep 2023
457 Beiträge
 
#6

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
486 Beiträge
 
Delphi 12 Athens
 
#7

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
Delphi.Narium

Registriert seit: 27. Nov 2017
2.597 Beiträge
 
Delphi 7 Professional
 
#8

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

  Alt 22. Mai 2025, 14:49
Ich trenne die UDPClients gleichzeitig! und genau dann tritt das Problem auf.
Trenne ich nur EINEN Client, passiert das Problem NICHT.
Tritt das Problem nicht auf oder dauert es nur ein fünfundreißigstel so lang (und fällt deshalb nicht auf)?

Zeigt doch einfach mal den Quellcode, mit dem die UDPClients gleichzeitig getrennt werden. Hier scheint ja das Problem zu liegen. Eventuell macht der VCL-Thread in der Zeit ja garnichts, sondern wird von Windows erst wieder an die Arbeit gelassen, wenn alle UDPClients beendet sind?

Mögliche blockierende Freigabeoperationen(?):

Socket-Cleanup bei UDP-Clients erfolgt synchron im Hauptthread?

Massenhafte Freigabe (35 Clients) blockiert die Nachrichtenverarbeitung?
  Mit Zitat antworten Zitat
QuickAndDirty

Registriert seit: 13. Jan 2004
Ort: Hamm(Westf)
2.058 Beiträge
 
Delphi 12 Athens
 
#9

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

  Alt 22. Mai 2025, 16:33
Läuft für jeden UDPClient eine SVCHOST.exe?
Andreas
Nobody goes there anymore. It's too crowded!
  Mit Zitat antworten Zitat
AJ_Oldendorf

Registriert seit: 12. Jun 2009
486 Beiträge
 
Delphi 12 Athens
 
#10

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

  Alt 23. Mai 2025, 05:08
Zitat:
Funktioniert das Debugging denn in anderen Projekten korrekt?
Es funktioniert auch in dem selben Projekt, wenn die VCL nicht hängt. Dann wird ganz normal die CPU Ansicht geöffnet. Es geht nur nicht, wenn die VCL hängt.

Zitat:
Tritt das Problem nicht auf oder dauert es nur ein fünfundreißigstel so lang (und fällt deshalb nicht auf)?

Zeigt doch einfach mal den Quellcode, mit dem die UDPClients gleichzeitig getrennt werden. Hier scheint ja das Problem zu liegen. Eventuell macht der VCL-Thread in der Zeit ja garnichts, sondern wird von Windows erst wieder an die Arbeit gelassen, wenn alle UDPClients beendet sind?

Mögliche blockierende Freigabeoperationen(?):

Socket-Cleanup bei UDP-Clients erfolgt synchron im Hauptthread?

Massenhafte Freigabe (35 Clients) blockiert die Nachrichtenverarbeitung?
Es wird einfach in einer Schleife, ein PostThreadMessage mit einer speziellen Nachrichtenkennung an die Threads geschickt, welche ja über das bekannte Konstrukt (PeekMessage) die Nachrichtenqueue ausliest und dort ein Terminate ausführt. Im Destroy des Threads, wird der UDPClient.Active := False zugewiesen und die Komponente freigegeben. Das wars.

Zitat:
Läuft für jeden UDPClient eine SVCHOST.exe?
Nein, sollte es denn?

Eine Sache habe ich mittlerweile rausgefunden.
Es liegt NICHT an UDP!
Ich habe im System noch viel mehr Threads und ich habe mal ein Test gemacht, andere Threads, die völlig andere Aufgaben haben, zu beenden.
Hier tritt das gleiche Problem auf. Es ist also ein grundlegendes Problem. Ich werde weiter suchen, woran das liegen könnte.

Daher nochmal meine Frage, ihr sprecht von Threadsicheren Listen und keine MessageQueue mit PeekMessage abgrasen und Events triggern. Habt ihr mal ein funktionierendes Beispiel, wie man ein Thread über so eine threadsichere Liste "Nachrichten" zukommen lassen kann und parallel dazu noch mit Events auf bestimmte Dinge triggern kann? Dann würde ich das auch gerne mal umbauen und versuchen
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 22:41 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