![]() |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Läuft für jeden UDPClient eine SVCHOST.exe?
|
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Zitat:
Delphi-Quellcode:
zugewiesen und die Komponente freigegeben. Das wars.
UDPClient.Active := False
Zitat:
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 |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Ein Profiler wird dir genau zeigen können, was in dem besagten Zeitraum im Code passiert und wo er gerade steht - das kann dir keiner hier sagen, solang es aus verständlichen Gründen nur Codeschnipsel gibt. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Es gibt allerdings lockfreie Queues mit denen das geht! Mann kann die als "Channel" benutzen. Die sind dann zwar Lockfrei jedoch erzeugen die für sich ne menge Aufwand...jedoch diesen aben vollständig ohne die Nebenläufigkeit zu behindern. Die ![]() Falls es die architektonish darum geht einige lang laufende Threads zu haben und diese immer weieder mal mit einer Aufgabe zu versorgen. Dieses problem verspricht die ![]() Ich warte noch auf eine mit "Fearless-Concurency" werbende Multithreading library. Die werde ich dann direkt übernehmen. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Wieder deinstalliert. Eurekalog installiert, im Projekt hinzugefügt, Hang Detection angeklickt und auf 1s gestellt. Anwendung gestartet, Fehlverhalten erzeugt (OnIdle Event wurde auch entsprechend 5s nicht aufgerufen und VCL hängt), Was müsste jetzt passieren? Eurekalog zeigt kein Fenster (hätte ich evtl. erwartet). Ich fahre die Anwendung runter. Auch keine LogDatei mit irgendwelchen Infos zu dem Hänger gefunden. Gibts noch ein Trick? Genau aus dem Grund, wollte ich es selber finden, da auch die Profiler keine Wunderlösung sind und entsprechend konfiguriert oder ähnliches gemacht werden muss. Ich sage nicht, dass die nicht funktionieren. Ich sage nur, es ist kein installieren und Fehler wurde gefunden im Programm. Hier vielleicht jemand ein Tipp dazu? Zitat:
Aber irgendwie scheint es keine Beispiele dazu zu geben, wo man sich das konkret angucken und nutzen könnte. Zum aktuellen Zeitpunkt helfen die Denkanstöße leider nicht wirklich |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Meine letzter Stand ist das wenn man es ganz genau nimmt keine block free Queue existiert.
Queue ist sie nicht wirklich "lock-free", sondern eher ein Thread-sicheres Kommunikationsmittel mit minimaler Sperrung, besonders optimiert für mehr Leser als Schreiber oder umgekehrt. Der Grund ist das immer TMonitor verwendet wird. Und TMonitor arbeitet mit lock. Ausnahme: Lock-Free Ring-Buffer. Habe aber keine Erfahrung damit. Übersicht: Option / Thread-sicher / Echt lock-free / Einfach zu nutzen / Performance TThreadedQueue<T> / ✅ / ❌ / ✅ / Hoch Deltics LockFreeQueue / ✅ / ✅ / ✅ / Sehr hoch Eigene Ring-Buffer / ✅ / ✅ / ❌ (komplex) Extrem hoch Windows SLIST APIs / ✅ / ✅ / ❌ (sehr komplex) Extrem hoch |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Eine Idee wäre: Ein array[0..N] of Queue, bei dem jeder Thread genau eine eigene Queue hat.
Delphi-Quellcode:
Keine Ahnung ob das geht. Aber so würde immer nur ein Thread schreiben und nur der Hauptthread lesen.
ThreadQueues: array[0..MaxThreads - 1] of TThreadedQueue<string>;
constructor TWorkerThread.Create(AQueueIndex: Integer); begin inherited Create(False); FQueueIndex := AQueueIndex; end; procedure TWorkerThread.Execute; var Msg: string; begin while not Terminated do begin Msg := Format('Thread %d arbeitet...', [FQueueIndex]); ThreadQueues[FQueueIndex].Enqueue(Msg); Sleep(Random(100)); end; end; |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Meine Idee dazu wäre ja, für jeden Thread eine eigene Liste anzulegen ähnlich dem Konstrukt was ich mal von Sebastian erhalten habe:
Delphi-Quellcode:
Das müsste soweit mit der Abarbeitung einer Liste mit Nachrichten ja gehen oder habe ich was übersehen?
TDataQueue = class
private FQueue: TQueue<TDataRec>; FLock: TCriticalSection; public constructor Create; destructor Destroy; override; procedure Enqueue(const Data: TDataRec); function Dequeue: TDataRec; end; constructor TDataQueue.Create; begin FQueue := TQueue<TDataRec>.Create; FLock := TCriticalSection.Create; end; destructor TDataQueue.Destroy; begin FQueue.Free; FLock.Free; inherited; end; procedure TDataQueue.Enqueue(const Data: TDataRec); begin FLock.Acquire; try FQueue.Enqueue(Data); finally FLock.Release; end; end; function TDataQueue.Dequeue: TDataRec; begin FLock.Acquire; try if FQueue.Count > 0 then Result := FQueue.Dequeue else begin Result.Clear; end; finally FLock.Release; end; end; TMyThread = class(TThread) private FDataQueue: TDataQueue; protected procedure Execute; override; public constructor Create(ADataQueue: TDataQueue); end; constructor TMyThread.Create(ADataQueue: TDataQueue); begin FDataQueue := ADataQueue; Inherited Create(False); end; procedure TMyThread.Execute; var RecData : TDataRec; begin while not Terminated do begin if Terminated then Exit; if Assigned(FDataQueue) then begin if FDataQueue.Count > 0 then begin RecData := FDataQueue.Dequeue; //Hier etwas mit den Daten/der Nachricht machen end else begin Sleep(1); end; end; end; end; Irgendein anderer Thread trägt dann in die Liste die Daten so ein:
Delphi-Quellcode:
FDataQueue.Enqueue(Daten);
Wie würde man aber das Konstrukt oben noch umbauen, damit es auch mit Events arbeitet. So pollt der Thread ja die ganze Zeit die Liste ab, deswegen auch das Sleep, damit die CPU Auslastung runter geht. Jetzt möchte ich dem Thread aber auch noch bestimmte Events schicken z.B. aus meiner Ursprungsvariante das PostThreadMessage zum terminieren des Threads |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Übrigens nochmal zu meinem Hauptproblem mit dem VCL Hänger.
Ich habe festgestellt, dass der Hänger nur passiert, wenn die Anwendung als 64bit compiliert wurde. Unter 32bit passiert es nicht. |
AW: Thread.Queue, Zeitmessung, Thread hängt angeblich
Zitat:
Wenn dir der standard reicht. Alle Objekte von Delphi haben einen monitor. Damit kannst du den zugriff auf dieses Objekt threadsicher machen. Das heist DU blockiert alle zugriffe auf das Objekt bis auf einen und alle threads warten in einer warte schlange und stehen so lange bis sie drann sind. TMonitor leistet das selbe wie TCriticalsection...nur das der Monitor halt schon teil des Objekts ist, während TCriticalsection von dir in alle möglichen kontexte gesetzt werden kann.
Delphi-Quellcode:
Das macht den Zugriff auf MessageQueue wenn konsequent über all so angewendet threadsicher, durch blockieren der nebenläufigkeit im Tmonitor.enter!
TMonitor.enter(MessageQueue);
try MessageQueue.add('einen text'); finally TMonitor.exit(MessageQueue); end; Threads können pausiert und aktiviert werden über TEvent...es ist ein signal
Delphi-Quellcode:
var ZweiThreadsKennenMich := TEvent.create;
ZweiThreadsKennenMich.ResetEvent; //Event Nicht triggered TTask.run( Procedure Begin if ZweiThreadsKennenMich.Waitfor(60000) = wrSignaled then PlaySound else begin //zu lange gewartet ZweiThreadsKennenMich.ResetEvent; end end ); ZweiThreadsKennenMich.SetEvent; // triggered das event und Sound wird abgespielt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:44 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