Delphi-PRAXiS
Seite 2 von 9     12 34     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Thread.Queue, Zeitmessung, Thread hängt angeblich (https://www.delphipraxis.net/217196-thread-queue-zeitmessung-thread-haengt-angeblich.html)

Rollo62 20. Mai 2025 13:00

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

Zitat von AJ_Oldendorf (Beitrag 1548742)
TL;DR; ?

Too long thread, didn't read ... (completely)



Zitat:

Zitat von AJ_Oldendorf (Beitrag 1548742)
Ich habe auch schon TStopwatch probiert. Kommt zum gleichen Ergebnis wie GetTickCount.

Ich meinte insbesondere diese Option, statt GetTickCount

Delphi-Quellcode:
class property IsHighResolution: Boolean read FIsHighResolution;
Die sollte dann einen HighResolution Timer nehmen, wenn auf True.
Ist womöglich weniger anfällig für Hänger, was noch zu beweisen wäre ... :stupid:

AJ_Oldendorf 20. Mai 2025 13:34

AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
 
IsHighResolution ist True.
TStopWatch liefert trotzdem ein ähnliches Ergebnis. Muss ich noch was umstellen bei TStopwatch?

Delphi-Quellcode:
while not Terminated do
begin

  //hier erfolgt eine Signalisierung über WaitForSingleObject und bei Timeout (=250ms), erfolgt der zyklische Aufruf unten
  if WaitForsingleObject(Irgendwas, 250, xxxx) = WAIT_OBJECT_0 do
  begin

  end;

  //zyklischer Aufruf
  var sw := TStopwatch.StartNew;

  //Synchronize(MeineFunktion);
  //Queue(Nil, MeineFunktion);
  ForceQueue(Nil, MeineFunktion);

  t1 := sw.ElapsedMilliseconds;
  //Protokollierung von t1 ...
end;

Rollo62 20. Mai 2025 13:56

AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
 
Dann hängt der HighResolution Timer wohl genauso.

Könnte es an der Schleife liegen, welche die Queue flutet?
Vielleicht versuchtst Du mal die Sequenz einzeln, ohne Schleife aufzurufen und zu messen,
oder zu versuchen wie oft der in die Queue läuft.

QuickAndDirty 20. Mai 2025 14:02

AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
 
Für mich sieht es so aus als ob das Protokoll verantwortlich ist. Auch wenn es mit Metacode und Brotkrumen an achtem Code immer etwas schwer zu verstehen ist...

Führe ein Protokoll für den Nebenthread das nur im Speicher geführt wird und im Nebenthread erzeugt wurde.
Dann übergebe das Protokoll in OnTerminate aus dem NebenThread in dein eigentliches Protokoll.

Nur so kannst du verhindern das ein Thread beim Protokolieren auf den anderen wartet.

AJ_Oldendorf 20. Mai 2025 14:21

AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
 
@QuickAndDirty:
Also, die VCL hängt. Wenn ich keine Protokollierung sondern nur ein Breakpoint auf die Abfrage >=200 mache, kommt er auch rein.
Ob ich es in ein Protokoll schreibe oder nicht, völlig egal. Es wird außerdem in das Protokoll mit "PostThreadMessage" eine Nachricht geschickt. Das führt nicht zu einem VCL Hänger.

Es passiert auch nur unter bestimmten Umständen (ich kann das provozieren).
Wenn alles "normal" läuft, geht der Thread auch durch diese Funktion und nichts wird protokolliert. Es ist also kein generelles Problem der Funktion. Deswegen glaube ich immernoch, dass der Thread "blockiert" bzw keine Rechenzeit mehr bekommt. So sieht es für mich irgendwie aus.

Uwe Raabe 20. Mai 2025 14:39

AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
 
Wenn du das provozieren kannst, dann sag doch mal wie. Vielleicht gibt das ja einen Hinweis auf die Ursache.

AJ_Oldendorf 20. Mai 2025 14:48

AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
 
In einem ganz anderen Thread sind ca 35 UDP Teilnehmer mit der Anwendung verbunden und wenn ich ca 10 Teilnehmer (oder auch mehr) die Verbindung trenne, dann passiert es. Aber auch erst zeitverzögert nach einigen Sekunden. Aber der Thread, der anscheinend hängt, hat damit gar nichts zu tun. Daher weiß ich nicht, ob das nur Zufall ist oder irgendwas mit Kontextwechseln zu tun haben könnte.

Ist es denn generell möglich, dass ein Thread, der gerade irgendwo läuft, geblockt wird von außen?
Natürlich ohne das dieser Thread auf irgendwas wartet. Also wie in meinem Beispiel unten, while not Terminated Schleife, Synchronize/Queue/ForceQueue und dann wird er "pausiert" und setzt dann aber genau an der Stelle fort?

Uwe Raabe 20. Mai 2025 15:04

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

Zitat von AJ_Oldendorf (Beitrag 1548757)
Ist es denn generell möglich, dass ein Thread, der gerade irgendwo läuft, geblockt wird von außen?

Na klar, dafür stellt Windows z.B. die Funktion SuspendThread zur Verfügung. Bei MadExcept gibt es auch eine Option pause all running delphi/bcb threads.

QuickAndDirty 20. Mai 2025 16:10

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

Zitat von AJ_Oldendorf (Beitrag 1548753)
Wenn alles "normal" läuft, geht der Thread auch durch diese Funktion und nichts wird protokolliert. Es ist also kein generelles Problem der Funktion. Deswegen glaube ich immernoch, dass der Thread "blockiert" bzw keine Rechenzeit mehr bekommt. So sieht es für mich irgendwie aus.

Interessant.
Ändert die ThreadPriority irgendetwas?
Es ist ja nun schon so, dass realistischer weise von den 200 threads von all den prozessen die laufen nur ein paar wirklich gleichzeitig laufen.
Allerdings weiß ich nicht wie genau sich prozess priorität und thread priorität addieren...multiplizieren...?
Aber da du eh schon alles ausprobiert hast, warum nicht auch thread priority?

Ich frage mich wirklich wie PostThreadMessage die Queue des Threads manipuliert ohne sich mit der MessageLoop des Threads zu synchronisieren. Ich suche ja schon länger nach einer einfachen Lockfree-Queue.

himitsu 20. Mai 2025 16:41

AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
 
Suspend sollte NIEMALS verwendet werden :!:
(OK, ein Thread sich selbst geht, aber auch da gibt es Besseres,
und von außerhalb ist es einfach nur gefährlich, da nicht bestimmt werden kann, ob an aktueller Stelle angehalten werden darf)

z.B. es wird grade ein String kopiert oder eine Speicheranforderung (delphis Speichermanager/FastMM) abgearbeitet
oder der Code ist grad in einer Sperre (CritticalSection oder so) drin, dann kannst du damit das komplette Programm (andere Threads) blockieren.

Andersrum kann ein Thread auch so blockiert werden (ohne ihn selbst anzuhalten) ... z.B. CriticalSections und Dergleichen.


Ob jetzt TStopwatch oder GetTickCount ist auch egal.
TStopwatch bietet ein paar nette Features und ist genauer.
GetTickCount hat auf vielen Systemen standardmäßig eine Auflösung von etwa 16 Millisekunden. (Kürzeres kann nicht gemessen werden und ist immer 0 und längeres wird gerundet)


Zitat:

Zitat von AJ_Oldendorf (Beitrag 1548710)
Ich wollte, das die VCL nicht mehr hängt, auf Queue umstellen und habe vor und nach dem Synchronize eine Zeitmessung eingebaut

Sowohl beim Synchronize, als auch beim Queue wird der Code (Funktion) im Hauptthread ausgeführt.
Für den Hauptthread macht es also keinen Unterschied,

außer dass beim Queue die Funktion nicht sofort, sondern erst später ausgeführt wird.
(Ausnahme, das Queue wird innerhalb des Hauptthreads ausgeführt, dann macht der Schrott nicht das, wonach es klingt, sondern führt es sofort aus, genauso wie beim Synchronize)
Bugfix: einfach immer ForceQueue statt Queue verwenden, das ist wirklich immer verzögert.

Ausnahme, der Hauptthread wartet auf diesen Thread (WaitFor oder sonstwas) oder auf etwas Anderes
und der Thread will ein Synchronize machen, wodurch er auf den Hautthread wartet (bis jener diese Funktion fertig ausgeführt hat),
aber da der Hauptthread wartet, kommt er nicht dazu das zu machen und beide warten bis in alle Ewigkeit.



Beim Queue ist die Zeitmessung aber auch bissl nutzlos, da es dort nur das Eintragen in die Liste misst, aber nicht die Funktion.
Wenn, dann innerhalb der Funktion messen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:14 Uhr.
Seite 2 von 9     12 34     Letzte »    

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