AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Threads (tpIdle) blokieren Anwendung
Thema durchsuchen
Ansicht
Themen-Optionen

Threads (tpIdle) blokieren Anwendung

Ein Thema von Manfred D2009 · begonnen am 14. Jun 2012 · letzter Beitrag vom 28. Jun 2012
Antwort Antwort
Manfred D2009

Registriert seit: 2. Jun 2009
25 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

Threads (tpIdle) blokieren Anwendung

  Alt 14. Jun 2012, 13:50
Hi DP,

ich habe eine GUI-Anwendung mit mehreren Berechnungs-Threads. Die Threads haben für bestimmte Aufgaben synchronisierte Abschnitte. Diese Abschnitte sind notwendig und sehr kurz (wenige Millisekunden). Die Threads haben die Priorität tpIdle.

Wenn ich nun mehrere Threads starte, wird die Bedienung meiner Hauptanwendung sehr, sehr holprig, da die Threads durch das ständige Synchronisieren das Hauptprogramm blockieren (oft im Sekundenbereich).

Jetzt könnte ich weniger Threads starten oder in der Execute-Routine der Threads Sleep-Aufrufe platzieren, dann würde die Anwendung wieder rennen. Allerdings will ich, dass die Threads die größtmögliche Leistung haben, wenn in der Anwendung sonst nichts passiert.

Was kann ich machen, damit Idle-Prozesse auch wirklich "idle" sind?
  Mit Zitat antworten Zitat
CCRDude

Registriert seit: 9. Jun 2011
678 Beiträge
 
FreePascal / Lazarus
 
#2

AW: Threads (tpIdle) blokieren Anwendung

  Alt 14. Jun 2012, 14:29
Die Threads sind ja wirklich idle, nur Deine Synchronisation nicht. Synchronisation ist auch das, was bei Threads nahezu die größte Herausforderung ist.

Lösungsansätze hängen ab von der konkreten Problemstellung.

Ein Ansatz, den ich neulich verfolgt habe, ist, die Daten enifach in Blöcken zusammenzufassen. So hat mein Code etwa alle Dateien der Platte aufgelistet und jeweils nur Blöcke zu Hundert Dateinamen synchronisiert. Der verarbeitende Thread brauchte eh länger, so dass dies kein Problem darstellte.

Weiterhin ist die Frage, ob die Hauptanwendung tatsächlich synchronisieren muss. Wenn es um Weiterverarbeitung geht, wäre noch ein weiterer Thread doch auf gut genug. Oder ein threadsicheres Datenobjekt. Wenn es dann um Visualisierung geht, könnte das UI in einem angemessenen zeitlichen Abstand pollen statt für jedes neue Datum eine Synchronisierung reinzubekommen. Beispiel: wenn es darum geht, wieviele Dateien schon verarbeitet wurden, reicht es, etwa per TMultiReadExclusiveWriteSynchronizer (bzw. performanterer Varianten)-Objekt die Statistik zu befüllen und dort per Timer nur 10 mal die Sekunde abzufragen und auf die GUI zu klatschen.

Diese beiden sind aber auch nur zwei Ansätze von etlichen...
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Threads (tpIdle) blokieren Anwendung

  Alt 14. Jun 2012, 14:32
Da du deine Delphi Version nicht bekannt gibst schau doch mal, ob du Delphi-Referenz durchsuchenTThread.Queue schon hast. Das ist Synchronisieren ohne Blockieren
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Manfred D2009

Registriert seit: 2. Jun 2009
25 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

AW: Threads (tpIdle) blokieren Anwendung

  Alt 14. Jun 2012, 15:56
Danke für die schnellen Antworten!

@Sir Rufo:
Ich habe D2009
Das mit der Queue ist sicher ein interessanter Ansatz, geht aber leider bei mir nicht so einfach, da die Berechnungs-Threads, wenn sie erstmal dran sind, die Queue füllen und dann die GUI wieder nicht wie gewünscht zum Zug kommt. Außerdem wären die nötigen Umbaumaßnahmen sehr groß.

@CCRDude:
Zitat:
Die Threads sind ja wirklich idle, nur Deine Synchronisation nicht.
Mir ist klar, dass die Abarbeitung einer synchronisierten Methode im MainThread stattfindet. Aber müsste nicht eigentlich ein idle-Thread gar nicht erst zum Absetzen seiner Synchronize-Routine kommen, wenn das Hauptprogramm was tun will? Werden die idle-Threads vom Betriebssystem so "hochpriorisiert", dass diese ihre sync. Methoden absetzen können und so den MainThread ausbremsen?

Ich kann leider nicht so einfach auf die Synchronize-Geschichten verzichten, da ich Ausgaben machen muss und an manchen Stellen threadsichere Datenzugriffe brauche.

Gib es vielleicht eine Möglichkeit um festzustellen, ob vor/nach einer zu synchronisierende Routine der MainThread noch etwas Wichtiges zu tun hat. Wenn ja, könnte man die Threads ja kurz mal schlafen legen...
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#5

AW: Threads (tpIdle) blokieren Anwendung

  Alt 15. Jun 2012, 01:13
da die Berechnungs-Threads, wenn sie erstmal dran sind, die Queue füllen und dann die GUI wieder nicht wie gewünscht zum Zug kommt.
Mhm, dass klingt so, als ob die synchronisierten Stellen sehr oft aufgerufen werden.

In dem Zusammenhang:
und an manchen Stellen threadsichere Datenzugriffe brauche.
Vermutlich wärst du da mit CriticalSections oder anderen feingranularen Synchronisationsmitteln besser dran.


Aber müsste nicht eigentlich ein idle-Thread gar nicht erst zum Absetzen seiner Synchronize-Routine kommen, wenn das Hauptprogramm was tun will?
Ich denke eher, dass das das Hauptprogramm gerade den synchronisierten Teil ausführt, wenn der Nutzer eigentlich was interaktives Machen will. Außerdem könnte es sein, dass Synchronisierungs-Nachrichten von der Anwendung/Windows gegenüber UI-Nachrichten bevorzugt werden

Auf einem Multicore-System könnten theoretisch auch Hauptthread und Idle-Thread gleichzeitig ausgeführt werden.
Intellekt ist das Verstehen von Wissen. Verstehen ist der wahre Pfad zu Einsicht. Einsicht ist der Schlüssel zu allem.

Geändert von BUG (15. Jun 2012 um 01:17 Uhr)
  Mit Zitat antworten Zitat
Manfred D2009

Registriert seit: 2. Jun 2009
25 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#6

AW: Threads (tpIdle) blokieren Anwendung

  Alt 15. Jun 2012, 07:15
@BUG:
Du hast recht, dass ich sehr häufig kleine synchronisierte Abschnitte lostrete. CriticalSections helfen zwar, die sync. Abschnitte zu verkleinern, aber auch in die threadsicheren Abschnitte darf trotzdem nur ein Prozess rein.

Und das Hauptproblem ist wohl, wie du sagst, dass auf einem Multicore-Rechner die Idle-Threads ja idle sind und deshalb weitermachen, ihre sync. Aufrufe loszuschicken.

Optimal für mich wäre eine Variante, bei der ich meine Threads bremse (evtl. mittels Sleep), wenn der Main-Prozess arbeitet und umgekehrt...
Gibt´s weitere Alternativen?
  Mit Zitat antworten Zitat
Antwort Antwort


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 05:57 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